Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-32874

CVE-2026-32874: Ultrajson Memory Leak DOS Vulnerability

CVE-2026-32874 is a memory leak denial of service vulnerability in Ultrajson that occurs when parsing large integers outside [-2^63, 2^64-1]. This article covers technical details, affected versions, impact, and mitigation.

Published:

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:

c
   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:

bash
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
bash
# 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.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.