CVE-2026-44660 Overview
CVE-2026-44660 is a memory leak vulnerability in UltraJSON (ujson), a fast JSON encoder and decoder written in pure C with bindings for Python 3.7+. When ujson.dump() writes to a file-like object and the underlying write operation raises an exception, the serialized JSON string object is not properly decremented. Each failed write operation leaks memory equal to the full size of the serialized payload. The flaw is tracked as [CWE-401] (Missing Release of Memory after Effective Lifetime) and is fixed in UltraJSON 5.12.1.
Critical Impact
Repeated failed ujson.dump() calls can exhaust process memory, leading to denial of service in long-running Python services that serialize JSON to unreliable sinks.
Affected Products
- UltraJSON (ujson) versions prior to 5.12.1
- Python 3.7+ applications using ujson.dump() with file-like objects
- Long-running services that serialize JSON to network sockets, pipes, or unreliable file handles
Discovery Timeline
- 2026-05-27 - CVE-2026-44660 published to NVD
- 2026-05-27 - Last updated in NVD database
Technical Details for CVE-2026-44660
Vulnerability Analysis
The vulnerability resides in the ujson.dump() function, which serializes a Python object to a JSON-formatted string and writes it to a file-like object via the object's write() method. UltraJSON allocates a Python string object to hold the serialized payload before delegating output to the caller-supplied stream.
When the write() call raises an exception, control returns to the caller without releasing the reference held by the serialized string. The reference counter is never decremented, so the CPython garbage collector cannot reclaim the allocation. Each failed invocation leaks memory equivalent to the full size of the serialized JSON payload.
The issue impacts availability rather than confidentiality or integrity. Attackers who can influence either the input payload size or the reliability of the write target can amplify the leak across many calls, exhausting heap memory in the host process.
Root Cause
The root cause is a missing Py_DECREF on the intermediate string object along the exception path inside the dump() implementation. Normal completion released the reference correctly, but the error branch did not. The fix in commit 82af1d0ac01d09aa40c887b460d44b9d9f4bccd9 adds the missing reference decrement so the object is freed regardless of whether the write succeeds.
Attack Vector
The attack vector is network-adjacent for services that accept attacker-influenced JSON payloads and write them to streams that can fail, such as broken TCP sockets, full pipes, or closed file descriptors. An attacker who can repeatedly trigger write failures during serialization causes incremental memory growth. Over time, the process exhausts available memory and crashes or is terminated by the operating system. No authentication or user interaction is required.
No verified public proof-of-concept code is available. Refer to the GitHub Security Advisory GHSA-c38f-wx89-p2xg for the maintainer's technical description.
Detection Methods for CVE-2026-44660
Indicators of Compromise
- Sustained, monotonic memory growth in Python processes that import ujson and call ujson.dump() against network sockets or pipes
- Repeated IOError, BrokenPipeError, or OSError exceptions originating from ujson.dump() call sites in application logs
- Out-of-memory (OOM) kills or container restarts on services that serialize large JSON payloads under unreliable I/O conditions
Detection Strategies
- Inventory Python dependencies across services and flag any ujson version below 5.12.1 using Software Composition Analysis tooling
- Instrument applications with tracemalloc or pympler to attribute allocation growth to UltraJSON serialization frames
- Correlate exception telemetry from ujson.dump() with process resident set size (RSS) trends in observability platforms
Monitoring Recommendations
- Track per-process RSS and Python heap metrics for services that perform JSON streaming to external sinks
- Alert on elevated rates of write-side I/O exceptions from JSON-emitting endpoints
- Audit dependency manifests (requirements.txt, pyproject.toml, Pipfile.lock) in CI for vulnerable ujson ranges
How to Mitigate CVE-2026-44660
Immediate Actions Required
- Upgrade UltraJSON to version 5.12.1 or later in all production and development environments
- Identify call sites of ujson.dump() that target network sockets, pipes, or other failure-prone streams and prioritize patching those services
- Recycle long-running Python worker processes after patching to release any leaked memory accumulated prior to the upgrade
Patch Information
The fix is included in UltraJSON release 5.12.1. The remediation commit is 82af1d0ac01d09aa40c887b460d44b9d9f4bccd9, which adds the missing reference decrement on the exception path inside dump(). Maintainer details are documented in GitHub Security Advisory GHSA-c38f-wx89-p2xg.
Workarounds
- Replace ujson.dump(obj, fp) with fp.write(ujson.dumps(obj)) wrapped in a try/except that releases local references on failure
- Set process-level memory limits and automatic restarts (for example, via systemd or Kubernetes resource limits) to contain leak impact until patching is complete
- Validate write-target health before serialization to reduce the frequency of exceptions raised during ujson.dump()
# Configuration example
pip install --upgrade 'ujson>=5.12.1'
pip show ujson | grep -i version
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

