Threats tagged 'ghsa-ghc9-756g-vrcv'
1 threat
Most recently published first
| Severity | CVSS | Signals | Threat | Source | Published | Score and star |
|---|---|---|---|---|---|---|
| Medium | 5.9 | EPSS 0.6% | Medium5.9EPSS 0.6%GCVE DatabaseCVE-2026-59171 ## 1. Executive Summary JSON-java version 20260522 contains an unguarded path from an HTTP request body to unbounded `BigInteger` and `BigDecimal` construction. `JSONTokener.nextSimpleValue()` accumulates numeric characters into a `StringBuilder` with no length cap, then passes the full string to `JSONObject.stringToNumber()`, which calls `new BigInteger(val)` or `new BigDecimal(val)` directly. Both constructors have polynomial time complexity (O(n^1.585) for `BigInteger`). A 488 KB JSON body — well within nginx's default 1 MB body-size limit — contains a 500,000-digit numeric literal that blocks the handling thread for approximately 3 seconds. Spring Boot has no default size limit for `application/json` request bodies. No parser configuration option (`withStrictMode`, `withKeepStrings`) prevents this. All three primary entry points are affected: `new JSONObject(String)`, `new JSONArray(String)`, and `XML.toJSONObject(String)`. This vulnerability is distinct from CVE-2023-5072 (which addressed `StackOverflowError` from deeply nested JSON *structures* via a `try/catch` in `nextValue()`) and from CVE-2022-45688 (which addressed recursive XML nesting depth). The numeric string length issue has been present since BigInteger support was introduced in release 20150729 and has never been fixed in any subsequent release. **Attack Complexity is rated High** because successful exploitation requires the target application to be using org.json specifically (rather than the default Jackson library used by Spring Boot), and requires the developer to have explicitly passed user-controlled input to `new JSONObject()` or equivalent. These are deployment conditions beyond the attacker's control. See Section 6 for the full CVSS rationale and Section 8 for the comparison with Jackson's treatment of the same issue class. This vulnerability was **reproduced locally against json-20260522.jar** with full evidence provided below. --- ## 2. Vulnerability Description `JSONTokener.nextSimpleValue()` accumulates characters into a `StringBuilder` with no length limit until it hits a structural JSON character: **`JSONTokener.java:500–504`:** ```java StringBuilder sb = new StringBuilder(); while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) { sb.append(c); // unbounded — no length check c = this.next(); } ``` The accumulated string is passed to `JSONObject.stringToValue()` → `stringToNumber()`, which calls `new BigInteger(val)` with zero size guard: **`JSONObject.java:2738`:** ```java BigInteger bi = new BigInteger(val); // val can be arbitrarily large; no guard ``` `BigInteger(String)` has O(n^1.585) time complexity due to its internal Karatsuba multiplication during construction. A 100,000-digit input takes ~120 ms; a 1,000,000-digit input takes ~12 seconds. The decimal path (`new BigDecimal(val)`, reached when the string contains a `.` or exponent) is equally affected. **No configuration option prevents this.** `withStrictMode(true)` and `withKeepStrings(true)` are not checked in the `nextSimpleValue()` → `stringToNumber()` call chain. Confirmed by execution: both options still produce BigInteger in ~120 ms for a 100K-digit input. **Relationship to CVE-2023-5072:** CVE-2023-5072 (fixed in release 20231013) catches `StackOverflowError` thrown by deeply nested JSON *structures* (`{[` brackets) inside `nextValue()`: ```java } catch (StackOverflowError e) { throw new JSONException("JSON Array or Object depth too large to process.", e); } ``` This fix is in `nextValue()` and covers only recursive object/array structure depth. It has no effect on the numeric string length path in `nextSimpleValue()` → `stringToNumber()`. The BigInteger length issue was not addressed in 20231013 or in any subsequent release. --- ## 3. Affected Code Locations | File | Lines | Description | |------|-------|-------------| | `JSONTokener.java` | 500–504 | `nextSimpleValue()` — unbounded character accumulation into `StringBuilder`, no length cap | | `JSONObject.java` | 2721–2748 | `stringToNumber()` — `new BigInteger(val)` / `new BigDecimal(val)` called directly with no length guard | --- ## 4. Proof of Concept (Locally Verified) ### 4.1 POC Code ```java import org.json.*; public class Poc2NumericDoSv2 { public static void main(String[] args) { System.out.println("=== CVE-002: JSONTokener Unbounded Numeric String DoS ==="); // Scaling: timing at different digit counts System.out.println("\n-- Unquoted numeric literal (JSONObject) --"); int[] sizes = {10_000, 100_000, 200_000, 500_000, 1_000_000}; for (int numLen : sizes) { String payload = "{\"x\":" + "9".repeat(numLen) + "}"; long start = System.currentTimeMillis(); JSONObject jo = new JSONObject(payload); long elapsed = System.currentTimeMillis() - start; System.out.printf(" %,7d digits (~%3d KB): %,5d ms type=%s%n", numLen, payload.length()/1024, elap | GCVE Database |
Page 1 of 1