VYPR
High severityNVD Advisory· Published Mar 20, 2026· Updated Mar 20, 2026

UltraJSON has a Memory Leak parsing large integers allows DoS

CVE-2026-32874

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.

PackageAffected versionsPatched versions
ujsonPyPI
>= 5.4.0, < 5.12.05.12.0

Affected products

2
  • Range: >=5.4.0, <=5.11.0
  • ultrajson/ultrajsonv5
    Range: >= 5.4.0, < 5.12.0

Patches

1
4baeb950df78

Fix memory leak parsing large integers

https://github.com/ultrajson/ultrajsonBrénainn WoodsendDec 10, 2025via ghsa
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

News mentions

0

No linked articles in our index yet.