From a16cb6a6078d76ddeaf715059213878d0ec7e057 Mon Sep 17 00:00:00 2001 From: Akriti Singh Date: Wed, 26 Jul 2023 16:11:37 +0530 Subject: [PATCH 1/3] Fixing vulnerability CVE-2023-34620 in hjson library by adding the implementation of maximum depth while parsing input JSON. --- src/main/org/hjson/HjsonParser.java | 31 +++++++++++++++++++++++------ src/main/org/hjson/JsonParser.java | 29 ++++++++++++++++++++------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/main/org/hjson/HjsonParser.java b/src/main/org/hjson/HjsonParser.java index fec6336..53ac492 100644 --- a/src/main/org/hjson/HjsonParser.java +++ b/src/main/org/hjson/HjsonParser.java @@ -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; @@ -111,14 +112,28 @@ 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 { + if(current==123) { + ++depth; + } + /* 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); + case '{': return readObject(false, depth); default: return readTfnns(); } + } private JsonValue readTfnns() throws IOException { @@ -161,7 +176,7 @@ private JsonValue readTfnns() throws IOException { } } - private JsonArray readArray() throws IOException { + private JsonArray readArray(int depth) throws IOException { read(); JsonArray array=new JsonArray(); skipWhiteSpace(); @@ -170,7 +185,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; @@ -180,6 +195,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(); @@ -196,7 +215,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 } diff --git a/src/main/org/hjson/JsonParser.java b/src/main/org/hjson/JsonParser.java index bbf7501..6e60c74 100644 --- a/src/main/org/hjson/JsonParser.java +++ b/src/main/org/hjson/JsonParser.java @@ -42,6 +42,7 @@ class JsonParser { private int current; private StringBuilder captureBuffer; private int captureStart; + private static final int MAX_DEPTH=1000; /* * | bufferOffset @@ -77,7 +78,21 @@ 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 { + if(current==123) { + ++depth; + } + /* 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(); @@ -88,9 +103,9 @@ private JsonValue readValue() throws IOException { case '"': return readString(); case '[': - return readArray(); + return readArray(depth); case '{': - return readObject(); + return readObject(depth); case '-': case '0': case '1': @@ -108,7 +123,7 @@ private JsonValue readValue() throws IOException { } } - private JsonArray readArray() throws IOException { + private JsonArray readArray(int depth) throws IOException { read(); JsonArray array=new JsonArray(); skipWhiteSpace(); @@ -117,7 +132,7 @@ private JsonArray readArray() throws IOException { } do { skipWhiteSpace(); - array.add(readValue()); + array.add(readValue(depth)); skipWhiteSpace(); } while (readIf(',')); if (!readIf(']')) { @@ -126,7 +141,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(); @@ -141,7 +156,7 @@ private JsonObject readObject() throws IOException { throw expected("':'"); } skipWhiteSpace(); - object.add(name, readValue()); + object.add(name, readValue(depth)); skipWhiteSpace(); } while (readIf(',')); if (!readIf('}')) { From 00e3b1325cb6c2b80b347dbec9181fd17ce0a599 Mon Sep 17 00:00:00 2001 From: trobro Date: Sat, 12 Aug 2023 15:51:12 +0200 Subject: [PATCH 2/3] general fix --- src/main/org/hjson/HjsonParser.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/org/hjson/HjsonParser.java b/src/main/org/hjson/HjsonParser.java index 53ac492..d80226d 100644 --- a/src/main/org/hjson/HjsonParser.java +++ b/src/main/org/hjson/HjsonParser.java @@ -117,9 +117,6 @@ private JsonValue readValue() throws IOException, ParseException { } private JsonValue readValue(int depth) throws IOException, ParseException { - if(current==123) { - ++depth; - } /* The following has been refrenced for the resolution of the vulnerability: https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b */ @@ -129,8 +126,8 @@ private JsonValue readValue(int depth) throws IOException, ParseException { switch(current) { case '\'': case '"': return readString(); - case '[': return readArray(depth); - case '{': return readObject(false, depth); + case '[': return readArray(depth + 1); + case '{': return readObject(false, depth + 1); default: return readTfnns(); } From 91bef056d56bf968451887421c89a44af1d692ff Mon Sep 17 00:00:00 2001 From: trobro Date: Sat, 12 Aug 2023 16:07:46 +0200 Subject: [PATCH 3/3] JsonParser too --- src/main/org/hjson/JsonParser.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/org/hjson/JsonParser.java b/src/main/org/hjson/JsonParser.java index 6e60c74..7e32608 100644 --- a/src/main/org/hjson/JsonParser.java +++ b/src/main/org/hjson/JsonParser.java @@ -84,9 +84,6 @@ private JsonValue readValue() throws IOException{ private JsonValue readValue(int depth) throws IOException { - if(current==123) { - ++depth; - } /* The following has been refrenced for the resolution of the vulnerability: https://github.com/FasterXML/jackson-databind/commit/fcfc4998ec23f0b1f7f8a9521c2b317b6c25892b */ @@ -103,9 +100,9 @@ private JsonValue readValue(int depth) throws IOException { case '"': return readString(); case '[': - return readArray(depth); + return readArray(depth + 1); case '{': - return readObject(depth); + return readObject(depth + 1); case '-': case '0': case '1':