You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@johnzon.apache.org by "Romain Manni-Bucau (JIRA)" <ji...@apache.org> on 2018/10/02 13:48:00 UTC
[jira] [Resolved] (JOHNZON-190) Issues when call close method more
than twice using Queue as buffer strategy.
[ https://issues.apache.org/jira/browse/JOHNZON-190?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Romain Manni-Bucau resolved JOHNZON-190.
----------------------------------------
Resolution: Fixed
Fix Version/s: 1.1.11
> Issues when call close method more than twice using Queue as buffer strategy.
> -----------------------------------------------------------------------------
>
> Key: JOHNZON-190
> URL: https://issues.apache.org/jira/browse/JOHNZON-190
> Project: Johnzon
> Issue Type: Bug
> Components: JSON-B
> Affects Versions: 1.1.10
> Reporter: Otavio Goncalves de Santana
> Priority: Major
> Fix For: 1.1.11
>
>
> Title: Issues when calling the close method more than twice using Queue as a buffer strategy.
>
> Hello everyone.
>
> I would like to report a bug within JsonGeneratorImpl. In the JsonGeneratorImpl has the BufferStrategy.BufferProvider<char[]> as an attribute.
> This BufferStrategy.BufferProvider either [put the buffer in the Queue|https://github.com/apache/johnzon/blob/d7a4a2f9de8c39b84fbb8b73b13c6f7f6514a9cf/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java#L466], whose uses the release *method*, and [feed|https://github.com/apache/johnzon/blob/d7a4a2f9de8c39b84fbb8b73b13c6f7f6514a9cf/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java#L72] the buffer using the *newBuffer* method.
>
> As consequences of this behavior there are two failures:
>
> # Waste of memory issue
>
> The code below, it will put the same value in the queue six times.
> {code:java}
> public class App {
> public static void main(String[] args) throws IOException {
> Path path = Paths.get("generated.json");
> OutputStream out = Files.newOutputStream(path);
> JsonGenerator jsonGen = Json.createGenerator(out);
> jsonGen.writeStartObject();
> jsonGen.write("false", JsonValue.FALSE);
> jsonGen.write("true", JsonValue.TRUE);
> jsonGen.writeEnd();
> jsonGen.close();
> jsonGen.close();
> jsonGen.close();
> jsonGen.close();
> jsonGen.close();
> jsonGen.close();
> }
> }
> {code}
> Doing a malicious code such as below, it will use a huge number of memory.
> {code:java}
> public class App1 {
> public static void main(String[] args) throws IOException {
> Path path = Paths.get("generated.json");
> OutputStream out = Files.newOutputStream(path);
> JsonGenerator jsonGen = Json.createGenerator(out);
> jsonGen.writeStartObject();
> jsonGen.write("false", JsonValue.FALSE);
> jsonGen.write("true", JsonValue.TRUE);
> jsonGen.writeEnd();
> while (true) {
> jsonGen.close();
> }
> }
> }
> {code}
> # The security issue
> It uses the value in the queue as a buffer; thereby, it is a security failure once a request can read information from another application, thus, an isolation issue.
> {code:java}
> public class App2 {
> public static void main(String[] args) throws Exception {
> Path path = Paths.get("generated2.json");
> OutputStream out = Files.newOutputStream(path);
> JsonGenerator jsonGen = Json.createGenerator(out);
> jsonGen.writeStartObject();
> jsonGen.write("keyA", JsonValue.FALSE);
> jsonGen.write("keyB", JsonValue.TRUE);
> jsonGen.writeEnd();
> jsonGen.close();
> Path path3 = Paths.get("generated3.json");
> OutputStream out2 = Files.newOutputStream(path3);
> JsonGenerator jsonGen2 = Json.createGenerator(out2);
> jsonGen2.writeStartObject();
> Field fieldBuffer = jsonGen2.getClass().getDeclaredField("buffer");
> fieldBuffer.setAccessible(true);
> char[] buffer = (char[]) fieldBuffer.get(jsonGen);
> String json = String.valueOf(buffer);
> System.out.println(json);
> jsonGen2.flush();
> }
> }
> {code}
> # Race condition issue:
> As the code below shows, given a mistake of twice close, To class can write using the same buffer, thereby, a write JSON mistake.
> {code:java}
> public class App3 {
> public static void main(String[] args) throws IOException {
> Path path = Paths.get("generated.json");
> OutputStream out = Files.newOutputStream(path);
> JsonGenerator jsonGen = Json.createGenerator(out);
> jsonGen.writeStartObject();
> jsonGen.write("false", JsonValue.FALSE);
> jsonGen.write("true", JsonValue.TRUE);
> jsonGen.writeEnd();
> jsonGen.close();
> jsonGen.close();
> Path path2 = Paths.get("generated2.json");
> OutputStream out2 = Files.newOutputStream(path2);
> JsonGenerator jsonGen2 = Json.createGenerator(out2);
> Path path3 = Paths.get("generated3.json");
> OutputStream out3 = Files.newOutputStream(path3);
> JsonGenerator jsonGen3 = Json.createGenerator(out3);
> jsonGen2.writeStartObject();
> jsonGen2.write("false1", JsonValue.FALSE);
> jsonGen2.write("true2", JsonValue.TRUE);
> jsonGen2.writeEnd();
> jsonGen3.writeStartObject();
> jsonGen3.write("false3", JsonValue.FALSE);
> jsonGen3.write("true4", JsonValue.TRUE);
> jsonGen3.writeEnd();
> jsonGen2.close();
> jsonGen3.close();
> }
> }
> {code}
> Output
> {code:json}
> Generated.json: {"false":false,"true":true}
> Generated2.json: {"false3":false,"true4":true}
> Generated3.json: {"false3":false,"true4":true}
> {code}
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)