UltraJSON has a Memory Leak parsing large integers allows DoS
Description
UltraJSON is a fast JSON encoder and decoder written in pure C with bindings for Python 3.7+. Versions 5.4.0 through 5.11.0 contain an accumulating memory leak in JSON parsing large (outside of the range [-2^63, 2^64 - 1]) integers. The leaked memory is a copy of the string form of the integer plus an additional NULL byte. The leak occurs irrespective of whether the integer parses successfully or is rejected due to having more than sys.get_int_max_str_digits() digits, meaning that any sized leak per malicious JSON can be achieved provided that there is no limit on the overall size of the payload. Any service that calls ujson.load()/ujson.loads()/ujson.decode() on untrusted inputs is affected and vulnerable to denial of service attacks. This issue has been fixed in version 5.12.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
UltraJSON 5.4.0 through 5.11.0 leaks memory when parsing large integers, enabling denial of service via untrusted JSON inputs.
Vulnerability
Overview
UltraJSON versions 5.4.0 through 5.11.0 contain an accumulating memory leak triggered during parsing of JSON integers that fall outside the range [-2^63, 2^64 - 1]. The leaked memory consists of a copy of the integer's string representation plus an additional NULL byte. This leak occurs regardless of whether the integer is successfully parsed or rejected due to exceeding sys.get_int_max_str_digits() digits, meaning an attacker can cause arbitrary memory consumption per malicious JSON payload as long as there is no overall payload size limit [1][4].
Exploitation
Any service that calls ujson.load(), ujson.loads(), or ujson.decode() on untrusted input is affected. An attacker can send a crafted JSON payload containing a very large integer (e.g., 2**64 or larger) to trigger the leak. Because the leak accumulates with each parsing operation, repeated submissions can exhaust available memory, leading to a denial of service condition. No authentication or special network position is required if the service accepts external JSON data [1][4].
Impact
Successful exploitation results in a denial of service (DoS) due to memory exhaustion. The vulnerability does not lead to code execution or data corruption, but it can render the affected service unavailable. The project's maintainers note that UltraJSON's architecture is fundamentally ill-suited to security changes and recommend migrating to orjson for new projects [3].
Mitigation
The issue has been fixed in UltraJSON version 5.12.0 [2]. Users should upgrade immediately. There are no workarounds other than upgrading to the patched version [4].
AI Insight generated on May 18, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
ujsonPyPI | >= 5.4.0, < 5.12.0 | 5.12.0 |
Affected products
2- ultrajson/ultrajsonv5Range: >= 5.4.0, < 5.12.0
Patches
14baeb950df78Fix memory leak parsing large integers
2 files changed · +17 −1
src/ujson/python/JSONtoObj.c+3 −1 modified@@ -145,7 +145,9 @@ static JSOBJ Object_newIntegerFromString(void *prv, char *value, size_t length) 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)
tests/test_ujson.py+14 −0 modified@@ -656,6 +656,20 @@ def test_encode_decode_big_int(i, mode): assert ujson.decode(json_string) == python_object +@pytest.mark.xfail( + sys.implementation.name == "pypy", + reason="PyPy's PyNumber_ToBase ignores sys.get_int_max_str_digits()", +) +def test_encode_too_big_int_error(): + with pytest.raises(ValueError, match="integer string conversion"): + ujson.dumps(pow(10, 10_000)) + + +def test_decode_too_big_int_error(): + with pytest.raises(ValueError, match="integer string conversion"): + ujson.loads("9" * 10_000) + + @pytest.mark.parametrize( "test_input, expected", [
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-wgvc-ghv9-3pmmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2026-32874ghsaADVISORY
- github.com/ultrajson/ultrajson/commit/4baeb950df780092bd3c89fc702a868e99a3a1d2ghsax_refsource_MISCWEB
- github.com/ultrajson/ultrajson/releases/tag/5.12.0ghsax_refsource_MISCWEB
- github.com/ultrajson/ultrajson/security/advisories/GHSA-wgvc-ghv9-3pmmghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.