Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing vulnerability CVE-2023-34620 in hjson library by adding the implementation of maximum depth while parsing input JSON. #26

Merged
merged 3 commits into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions src/main/org/hjson/HjsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class HjsonParser {
private StringBuilder captureBuffer, peek;
private boolean capture;
private boolean legacyRoot;
private static final int MAX_DEPTH=1000;

private IHjsonDsfProvider[] dsfProviders;

Expand Down Expand Up @@ -111,14 +112,25 @@ JsonValue checkTrailing(JsonValue v) throws ParseException, IOException {
return v;
}

private JsonValue readValue() throws IOException {
private JsonValue readValue() throws IOException, ParseException {
return readValue(0);
}

private JsonValue readValue(int depth) throws IOException, ParseException {
/* The following has been refrenced for the resolution of the vulnerability:
https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b
*/
if(depth>MAX_DEPTH) {
throw error("The passed json has exhausted the depth supported of "+MAX_DEPTH+".");
}
switch(current) {
case '\'':
case '"': return readString();
case '[': return readArray();
case '{': return readObject(false);
case '[': return readArray(depth + 1);
case '{': return readObject(false, depth + 1);
default: return readTfnns();
}

}

private JsonValue readTfnns() throws IOException {
Expand Down Expand Up @@ -161,7 +173,7 @@ private JsonValue readTfnns() throws IOException {
}
}

private JsonArray readArray() throws IOException {
private JsonArray readArray(int depth) throws IOException {
read();
JsonArray array=new JsonArray();
skipWhiteSpace();
Expand All @@ -170,7 +182,7 @@ private JsonArray readArray() throws IOException {
}
while (true) {
skipWhiteSpace();
array.add(readValue());
array.add(readValue(depth));
skipWhiteSpace();
if (readIf(',')) skipWhiteSpace(); // , is optional
if (readIf(']')) break;
Expand All @@ -180,6 +192,10 @@ private JsonArray readArray() throws IOException {
}

private JsonObject readObject(boolean objectWithoutBraces) throws IOException {
return this.readObject(objectWithoutBraces, 0);
}

private JsonObject readObject(boolean objectWithoutBraces, int depth) throws IOException, ParseException {
if (!objectWithoutBraces) read();
JsonObject object=new JsonObject();
skipWhiteSpace();
Expand All @@ -196,7 +212,7 @@ private JsonObject readObject(boolean objectWithoutBraces) throws IOException {
throw expected("':'");
}
skipWhiteSpace();
object.add(name, readValue());
object.add(name, readValue(depth));
skipWhiteSpace();
if (readIf(',')) skipWhiteSpace(); // , is optional
}
Expand Down
26 changes: 19 additions & 7 deletions src/main/org/hjson/JsonParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class JsonParser {
private int current;
private StringBuilder captureBuffer;
private int captureStart;
private static final int MAX_DEPTH=1000;

/*
* | bufferOffset
Expand Down Expand Up @@ -77,7 +78,18 @@ JsonValue parse() throws IOException {
return result;
}

private JsonValue readValue() throws IOException {
private JsonValue readValue() throws IOException{
return readValue(0);
}


private JsonValue readValue(int depth) throws IOException {
/* The following has been refrenced for the resolution of the vulnerability:
https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b
*/
if(depth>MAX_DEPTH) {
throw error("The passed json has exhausted the maximum supported depth of "+MAX_DEPTH+".");
}
switch(current) {
case 'n':
return readNull();
Expand All @@ -88,9 +100,9 @@ private JsonValue readValue() throws IOException {
case '"':
return readString();
case '[':
return readArray();
return readArray(depth + 1);
case '{':
return readObject();
return readObject(depth + 1);
case '-':
case '0':
case '1':
Expand All @@ -108,7 +120,7 @@ private JsonValue readValue() throws IOException {
}
}

private JsonArray readArray() throws IOException {
private JsonArray readArray(int depth) throws IOException {
read();
JsonArray array=new JsonArray();
skipWhiteSpace();
Expand All @@ -117,7 +129,7 @@ private JsonArray readArray() throws IOException {
}
do {
skipWhiteSpace();
array.add(readValue());
array.add(readValue(depth));
skipWhiteSpace();
} while (readIf(','));
if (!readIf(']')) {
Expand All @@ -126,7 +138,7 @@ private JsonArray readArray() throws IOException {
return array;
}

private JsonObject readObject() throws IOException {
private JsonObject readObject(int depth) throws IOException {
read();
JsonObject object=new JsonObject();
skipWhiteSpace();
Expand All @@ -141,7 +153,7 @@ private JsonObject readObject() throws IOException {
throw expected("':'");
}
skipWhiteSpace();
object.add(name, readValue());
object.add(name, readValue(depth));
skipWhiteSpace();
} while (readIf(','));
if (!readIf('}')) {
Expand Down