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)