CVE-2025-67726 Overview
CVE-2025-67726 is a denial-of-service (DoS) vulnerability in Tornado, a Python web framework and asynchronous networking library. Versions 6.5.2 and below contain an inefficient algorithm in the _parseparam function within httputil.py that processes HTTP header parameters. The function repeatedly calls string.count() within a nested loop while parsing quoted semicolons, producing quadratic time complexity. An attacker can send a crafted Content-Disposition header with many parameters to drive CPU usage up at an O(n²) rate. Because Tornado uses a single event loop, one malicious request can render the entire server unresponsive. The issue is fixed in version 6.5.3.
Critical Impact
A single unauthenticated HTTP request with a malicious Content-Disposition header can stall the Tornado event loop and cause server-wide unavailability.
Affected Products
- Tornado versions 6.5.2 and earlier
- Python web applications built on the Tornado framework
- Async networking services using Tornado's httputil parsing layer
Discovery Timeline
- 2025-12-12 - CVE-2025-67726 published to NVD
- 2025-12-22 - Last updated in NVD database
Technical Details for CVE-2025-67726
Vulnerability Analysis
The flaw resides in Tornado's _parseparam helper in tornado/httputil.py, which splits HTTP header values such as multipart/form-data boundaries and Content-Disposition parameters on semicolons while respecting quoted strings. The original implementation re-scanned the entire string with s.count('"', 0, end) and s.count('\\"', 0, end) on every iteration of an inner loop. As the number of semicolons inside quoted regions grows, the work performed grows quadratically with input length. Tornado's single-threaded event loop magnifies the impact: while one worker is blocked parsing a malicious header, all other clients are starved. This pattern maps to [CWE-400] Uncontrolled Resource Consumption.
Root Cause
The root cause is an algorithmic complexity defect. The inner while loop advanced end one semicolon at a time and recounted quote characters from index 0 on each pass. Attacker-controlled input containing many semicolons inside quoted parameter values triggered repeated full scans, producing O(n²) CPU cost.
Attack Vector
The attack vector is network-based and requires no authentication or user interaction. An attacker submits an HTTP request whose Content-Disposition (or similar parameter-bearing) header carries a large number of crafted quoted semicolons. Tornado parses the header before application-level controls execute, so the event loop blocks during parsing. Repeated requests can sustain the outage.
# Patch from tornado/httputil.py - Fix quadratic behavior in _parseparam
def _parseparam(s: str) -> Generator[str, None, None]:
start = 0
while s.find(";", start) == start:
start += 1
end = s.find(";", start)
ind, diff = start, 0
while end > 0:
diff += s.count('"', ind, end) - s.count('\\"', ind, end)
if diff % 2 == 0:
break
Source: Tornado commit 771472c
The fix borrows logic from CPython PR 136072. It tracks a running diff of unescaped quote counts across incremental ranges (ind to end) rather than rescanning from index 0, restoring linear complexity.
Detection Methods for CVE-2025-67726
Indicators of Compromise
- HTTP requests with Content-Disposition headers exceeding typical size, containing dense sequences of quoted semicolons.
- Sustained CPU saturation in Tornado worker processes correlated with inbound HTTP traffic.
- Tornado event loop responsiveness alarms or health-check failures during request bursts.
- Access logs showing the same client repeatedly POSTing multipart/form-data with oversized parameter headers.
Detection Strategies
- Inspect inbound HTTP headers at the reverse proxy or WAF for Content-Disposition values above a reasonable byte threshold (for example, 4 KB) and for unusually high semicolon counts.
- Profile Tornado processes for long-running synchronous work inside httputil._parseparam using py-spy or similar samplers.
- Correlate spikes in per-request handler latency with specific source IPs in access logs.
Monitoring Recommendations
- Alert on Tornado worker CPU utilization sustained above baseline during off-peak windows.
- Track event loop lag metrics and request queue depth; both rise sharply during exploitation.
- Forward web server and reverse proxy logs to a centralized analytics platform for header-anomaly hunting.
How to Mitigate CVE-2025-67726
Immediate Actions Required
- Upgrade Tornado to version 6.5.3 or later in all production and staging environments.
- Inventory Python services and CI pipelines for transitive dependencies on tornado<=6.5.2.
- Enforce request and header size limits at the upstream proxy to cap parser input.
- Rate-limit unauthenticated POST endpoints that accept multipart/form-data payloads.
Patch Information
The maintainers fixed the issue in Tornado v6.5.3. Technical details and credit are documented in GitHub Security Advisory GHSA-jhmp-mqwm-3gq8. The code change is tracked in commit 771472c.
Workarounds
- Reject requests whose Content-Disposition header exceeds a strict byte limit at the WAF or load balancer.
- Drop requests with abnormal semicolon density in HTTP parameter headers using a regex or Lua filter.
- Place Tornado behind a reverse proxy that pre-parses and validates multipart headers before forwarding.
- Run multiple Tornado worker processes so a single blocked event loop does not take down the entire service.
# Upgrade Tornado to the patched release
pip install --upgrade 'tornado>=6.5.3'
# Verify installed version
python -c "import tornado; print(tornado.version)"
# Example NGINX limits in front of Tornado
# nginx.conf
# large_client_header_buffers 4 8k;
# client_header_buffer_size 4k;
# client_max_body_size 10m;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.


