You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@johnzon.apache.org by "Otavio Goncalves de Santana (JIRA)" <ji...@apache.org> on 2018/10/02 13:19:00 UTC

[jira] [Created] (JOHNZON-190) Issues when call close method more than twice using Queue as buffer strategy.

Otavio Goncalves de Santana created JOHNZON-190:
---------------------------------------------------

             Summary: 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


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)