CVE-2026-32874 Overview
UltraJSON (ujson) is a fast JSON encoder and decoder written in pure C with bindings for Python 3.7+. A memory leak vulnerability has been identified in versions 5.4.0 through 5.11.0 that occurs when parsing large integers outside the range [-2^63, 2^64 - 1]. The leaked memory consists of a copy of the string form of the integer plus an additional NULL byte. This vulnerability enables attackers to craft malicious JSON payloads that cause unbounded memory consumption, leading to denial of service conditions.
Critical Impact
Services calling ujson.load(), ujson.loads(), or ujson.decode() on untrusted inputs are vulnerable to denial of service attacks through memory exhaustion. The leak occurs regardless of whether the integer parses successfully or is rejected.
Affected Products
- UltraJSON versions 5.4.0 through 5.11.0
- Python applications using ujson for JSON parsing
- Web services and APIs accepting untrusted JSON input via ujson
Discovery Timeline
- 2026-03-20 - CVE CVE-2026-32874 published to NVD
- 2026-03-23 - Last updated in NVD database
Technical Details for CVE-2026-32874
Vulnerability Analysis
This vulnerability is classified as CWE-401 (Missing Release of Memory after Effective Lifetime), commonly known as a memory leak. The flaw exists in the JSON parsing code within src/ujson/python/JSONtoObj.c where memory allocated for parsing large integers is never freed after use.
When parsing integers that exceed the standard 64-bit range, the code allocates a buffer using PyObject_Malloc() to store the string representation of the number. However, after calling PyLong_FromString() to convert this buffer to a Python long integer, the allocated buffer was never released back to the memory pool.
The vulnerability is particularly dangerous because the leak occurs irrespective of whether the integer parsing succeeds or fails. Even when an integer is rejected due to exceeding sys.get_int_max_str_digits() limits, the memory still leaks. This means attackers can achieve arbitrary-sized memory leaks by crafting JSON payloads with extremely large integer strings, as long as there are no restrictions on the overall payload size.
Root Cause
The root cause is a missing PyObject_Free() call in the integer parsing function. When a buffer is allocated to hold the string representation of a large integer for conversion, the function returns the result of PyLong_FromString() directly without first freeing the allocated buffer. This creates an accumulating memory leak where each large integer parsed consumes additional memory that is never reclaimed.
Attack Vector
The attack vector is network-based and requires no authentication or user interaction. An attacker can exploit this vulnerability by sending specially crafted JSON payloads containing large integers to any service that uses ujson to parse untrusted input. By repeatedly sending such payloads or including multiple large integers in a single payload, an attacker can exhaust available memory on the target system.
The following code shows the security patch that fixes the memory leak:
char *buf = PyObject_Malloc(length + 1);
memcpy(buf, value, length);
buf[length] = '\0';
- return PyLong_FromString(buf, NULL, 10);
+ PyObject *ret = PyLong_FromString(buf, NULL, 10);
+ PyObject_Free(buf);
+ return ret;
}
static JSOBJ Object_newDouble(void *prv, double value)
Source: GitHub Commit 4baeb950
Detection Methods for CVE-2026-32874
Indicators of Compromise
- Unusual memory growth in Python processes using ujson without corresponding release
- Out-of-memory (OOM) killer events targeting services that parse JSON input
- Incoming JSON requests containing extremely large integer values (strings with hundreds or thousands of digits)
- Gradual memory exhaustion on systems processing high volumes of JSON data
Detection Strategies
- Monitor memory consumption patterns for Python applications using ujson, particularly looking for monotonically increasing memory usage
- Implement input validation to reject JSON payloads containing integers with excessive digit counts before passing to ujson
- Use application performance monitoring (APM) tools to track memory allocation patterns and identify leaks
- Deploy SentinelOne Singularity Platform to detect resource exhaustion attacks and anomalous process behavior
Monitoring Recommendations
- Set up alerts for memory usage thresholds on services parsing untrusted JSON input
- Monitor for repeated requests from single sources containing unusually large numeric values
- Track the ratio of incoming request size to memory consumption for JSON parsing services
- Implement logging for rejected integer parsing attempts that may indicate exploitation attempts
How to Mitigate CVE-2026-32874
Immediate Actions Required
- Upgrade UltraJSON to version 5.12.0 or later immediately on all affected systems
- Audit applications to identify all instances of ujson.load(), ujson.loads(), and ujson.decode() processing untrusted input
- Implement input size limits on JSON payloads at the web server or load balancer level
- Consider temporarily switching to Python's built-in json module for untrusted input processing until patching is complete
Patch Information
The vulnerability has been fixed in UltraJSON version 5.12.0. The patch adds proper memory deallocation by calling PyObject_Free(buf) after converting the integer string, ensuring the allocated buffer is released. Users should upgrade immediately by running:
pip install ujson>=5.12.0
For detailed information about the fix, refer to the GitHub Security Advisory GHSA-wgvc-ghv9-3pmm and the version 5.12.0 release notes.
Workarounds
- Implement request size limits to restrict the maximum size of JSON payloads accepted by your service
- Add validation middleware to reject JSON containing integers beyond reasonable bounds before ujson processing
- Use Python's standard json library for parsing untrusted input as a temporary alternative
- Deploy rate limiting to reduce the impact of potential exploitation attempts
# Upgrade ujson to patched version
pip install --upgrade ujson>=5.12.0
# Verify installed version
pip show ujson | grep Version
# Alternative: pin to fixed version in requirements.txt
echo "ujson>=5.12.0" >> requirements.txt
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

