Skip to content

Commit 2510b41

Browse files
fix CVE-2024-57699 for predefined parsers
1 parent 7f01adf commit 2510b41

File tree

3 files changed

+91
-25
lines changed

3 files changed

+91
-25
lines changed

README.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ So I do not use my json-smart anymore. I had fun with this project. If you want
1919

2020
# Changelog
2121

22+
## *V 2.5.2* (2025-02-07)
23+
24+
* Fix CVE-2024-57699 for predefined parsers
25+
2226
### *V 2.5.1* (2024-03-14)
2327

2428
* Bump all dependencies.
@@ -122,4 +126,4 @@ So I do not use my json-smart anymore. I had fun with this project. If you want
122126

123127
### *V 2.0-RC1* (2012-02-18)
124128
* speed improvement in POJO manipulation
125-
* add JSONStyle.LT_COMPRESS predefined generate strct json, but ignoring / escapement.
129+
* add JSONStyle.LT_COMPRESS predefined generate strct json, but ignoring / escapement.

json-smart/src/main/java/net/minidev/json/parser/JSONParser.java

+24-24
Original file line numberDiff line numberDiff line change
@@ -41,55 +41,55 @@ public class JSONParser {
4141
public final static int IGNORE_CONTROL_CHAR = 8;
4242
/**
4343
* Use int datatype to store number when it's possible.
44-
*
44+
*
4545
* @since 1.0.7
4646
*/
4747
public final static int USE_INTEGER_STORAGE = 16;
4848
/**
4949
* Throws exception on excessive 0 leading in digits
50-
*
50+
*
5151
* @since 1.0.7
5252
*/
5353
public final static int ACCEPT_LEADING_ZERO = 32;
5454
/**
5555
* Throws exception on useless comma in object and array
56-
*
56+
*
5757
* @since 1.0.8
5858
*/
5959
public final static int ACCEPT_USELESS_COMMA = 64;
6060
/**
6161
* Allow Json-smart to use Double or BigDecimal to store floating point
6262
* value
63-
*
63+
*
6464
* You may need to disable HI_PRECISION_FLOAT feature on 32bit to improve
6565
* parsing performances.
66-
*
66+
*
6767
* @since 1.0.9
6868
*/
6969
public final static int USE_HI_PRECISION_FLOAT = 128;
7070
/**
7171
* If enabled json-smart will throws exception if datas are present after
7272
* the end of the Json data.
73-
*
73+
*
7474
* @since 1.0.9-2
7575
*/
7676
public final static int ACCEPT_TAILLING_DATA = 256;
7777
/**
7878
* smart mode, fastest parsing mode. accept lots of non standard json syntax
79-
*
79+
*
8080
* @since 2.0.1
8181
*/
8282
public final static int ACCEPT_TAILLING_SPACE = 512;
8383
/**
8484
* smart mode, fastest parsing mode. accept lots of non standard json syntax
85-
*
85+
*
8686
* @since 2.2.2
8787
*/
8888
public final static int REJECT_127_CHAR = 1024;
8989

9090
/**
9191
* Use double if possible for big digits, if no precision lost is observed
92-
*
92+
*
9393
* @since 2.4
9494
*/
9595
public final static int BIG_DIGIT_UNRESTRICTED = 2048;
@@ -100,36 +100,36 @@ public class JSONParser {
100100
* @since 2.5
101101
*/
102102
public static final int LIMIT_JSON_DEPTH = 4096;
103-
104-
103+
104+
105105
/**
106106
* smart mode, fastest parsing mode. accept lots of non standard json syntax
107-
*
107+
*
108108
* @since 1.0.6
109109
*/
110110
public final static int MODE_PERMISSIVE = -1;
111111
/**
112112
* strict RFC4627 mode.
113-
*
113+
*
114114
* slower than PERMISSIVE MODE.
115-
*
115+
*
116116
* @since 1.0.6
117117
*/
118-
public final static int MODE_RFC4627 = USE_INTEGER_STORAGE | USE_HI_PRECISION_FLOAT | ACCEPT_TAILLING_SPACE;
118+
public final static int MODE_RFC4627 = USE_INTEGER_STORAGE | USE_HI_PRECISION_FLOAT | ACCEPT_TAILLING_SPACE | LIMIT_JSON_DEPTH;
119119
/**
120120
* Parse Object like json-simple
121-
*
121+
*
122122
* Best for an iso-bug json-simple API port.
123-
*
123+
*
124124
* @since 1.0.7
125125
*/
126-
public final static int MODE_JSON_SIMPLE = ACCEPT_USELESS_COMMA | USE_HI_PRECISION_FLOAT | ACCEPT_TAILLING_DATA | ACCEPT_TAILLING_SPACE | REJECT_127_CHAR | BIG_DIGIT_UNRESTRICTED;
126+
public final static int MODE_JSON_SIMPLE = ACCEPT_USELESS_COMMA | USE_HI_PRECISION_FLOAT | ACCEPT_TAILLING_DATA | ACCEPT_TAILLING_SPACE | REJECT_127_CHAR | BIG_DIGIT_UNRESTRICTED | LIMIT_JSON_DEPTH;
127127
/**
128128
* Strictest parsing mode
129-
*
129+
*
130130
* @since 2.0.1
131131
*/
132-
public final static int MODE_STRICTEST = USE_INTEGER_STORAGE | USE_HI_PRECISION_FLOAT | REJECT_127_CHAR;
132+
public final static int MODE_STRICTEST = USE_INTEGER_STORAGE | USE_HI_PRECISION_FLOAT | REJECT_127_CHAR | LIMIT_JSON_DEPTH;
133133
/**
134134
* Default json-smart processing mode
135135
*/
@@ -154,7 +154,7 @@ private JSONParserReader getPStream() {
154154

155155
/**
156156
* cached constructor
157-
*
157+
*
158158
* @return instance of JSONParserInputStream
159159
*/
160160
private JSONParserInputStream getPBinStream() {
@@ -165,7 +165,7 @@ private JSONParserInputStream getPBinStream() {
165165

166166
/**
167167
* cached constructor
168-
*
168+
*
169169
* @return instance of JSONParserString
170170
*/
171171
private JSONParserString getPString() {
@@ -176,7 +176,7 @@ private JSONParserString getPString() {
176176

177177
/**
178178
* cached constructor
179-
*
179+
*
180180
* @return instance of JSONParserByteArray
181181
*/
182182
private JSONParserByteArray getPBytes() {
@@ -223,7 +223,7 @@ public <T> T parse(byte[] in, Class<T> mapTo) throws ParseException {
223223
/**
224224
* use to return Primitive Type, or String, Or JsonObject or JsonArray
225225
* generated by a ContainerFactory
226-
* @throws UnsupportedEncodingException
226+
* @throws UnsupportedEncodingException
227227
*/
228228
public Object parse(InputStream in) throws ParseException, UnsupportedEncodingException {
229229
return getPBinStream().parse(in);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package net.minidev.json.test;
2+
3+
import net.minidev.json.parser.JSONParser;
4+
import net.minidev.json.parser.ParseException;
5+
import org.junit.jupiter.api.Test;
6+
7+
import static org.junit.jupiter.api.Assertions.assertThrows;
8+
9+
public class TestCVE202457699 {
10+
11+
@Test
12+
public void jsonSimpleParserShouldRestrictDepth() {
13+
// Create a Malicious JSON String
14+
StringBuilder s = createMaliciousString();
15+
JSONParser p = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
16+
assertThrows(ParseException.class,
17+
() -> p.parse(s.toString()),
18+
"Malicious payload, having non natural depths");
19+
}
20+
21+
@Test
22+
public void strictestParserShouldRestrictDepth() {
23+
// Create a Malicious JSON String
24+
StringBuilder s = createMaliciousString();
25+
JSONParser p = new JSONParser(JSONParser.MODE_STRICTEST);
26+
assertThrows(ParseException.class,
27+
() -> p.parse(s.toString()),
28+
"Malicious payload, having non natural depths");
29+
}
30+
31+
@Test
32+
public void rfc4627ParserShouldRestrictDepth() {
33+
// Create a Malicious JSON String
34+
StringBuilder s = createMaliciousString();
35+
JSONParser p = new JSONParser(JSONParser.MODE_RFC4627);
36+
assertThrows(ParseException.class,
37+
() -> p.parse(s.toString()),
38+
"Malicious payload, having non natural depths");
39+
}
40+
41+
@Test
42+
public void permissiveParserShouldRestrictDepth() {
43+
// Create a Malicious JSON String
44+
StringBuilder s = createMaliciousString();
45+
JSONParser p = new JSONParser(JSONParser.MODE_PERMISSIVE);
46+
assertThrows(ParseException.class,
47+
() -> p.parse(s.toString()),
48+
"Malicious payload, having non natural depths");
49+
}
50+
51+
private static StringBuilder createMaliciousString() {
52+
StringBuilder s = new StringBuilder();
53+
for (int i = 0; i < 10000 ; i++) {
54+
s.append("{\"a\":");
55+
}
56+
s.append("1");
57+
for (int i = 0; i < 10000 ; i++) {
58+
s.append("}");
59+
}
60+
return s;
61+
}
62+
}

0 commit comments

Comments
 (0)