CVE-2025-67724
📋 TL;DR
This vulnerability in Tornado web framework allows attackers to inject malicious content into HTTP headers or execute cross-site scripting (XSS) attacks by passing untrusted data to the 'reason' argument in HTTP status methods. It affects applications using Tornado versions 6.5.2 and below that accept user input for custom HTTP status messages. The vulnerability can be exploited through both RequestHandler.set_status and tornado.web.HTTPError methods.
💻 Affected Systems
- Tornado web framework
📦 What is this software?
Tornado by Tornadoweb
⚠️ Risk & Real-World Impact
Worst Case
Attackers could inject arbitrary HTTP headers leading to cache poisoning, session hijacking, or redirect users to malicious sites. In XSS scenarios, they could steal session cookies, perform actions as authenticated users, or deface websites.
Likely Case
Cross-site scripting attacks where attackers inject malicious JavaScript into error pages, potentially stealing user credentials or session data from users who encounter crafted error responses.
If Mitigated
With proper input validation and output encoding, the risk is reduced to minimal, though the underlying vulnerability remains present in the framework.
🎯 Exploit Status
Exploitation requires applications to pass user-controlled data to the vulnerable 'reason' parameter. The advisory includes technical details that could be used to create exploits.
🛠️ Fix & Mitigation
✅ Official Fix
Patch Version: 6.5.3
Vendor Advisory: https://github.com/tornadoweb/tornado/security/advisories/GHSA-pr2v-jx2c-wg9f
Restart Required: Yes
Instructions:
1. Update Tornado using pip: 'pip install tornado==6.5.3' or 'pip install --upgrade tornado'
2. Restart all Tornado-based applications
3. Verify the update with 'pip show tornado'
🔧 Temporary Workarounds
Input validation and sanitization
allImplement strict input validation and output encoding for any data passed to the 'reason' argument in HTTP status methods
Disable custom reason phrases
allAvoid using custom reason phrases in HTTP responses by not passing user input to set_status() or HTTPError reason parameter
🧯 If You Can't Patch
- Implement strict input validation to sanitize any user data before passing it to HTTP status methods
- Add output encoding for HTTP headers and HTML responses to prevent injection attacks
🔍 How to Verify
Check if Vulnerable:
Check if your Tornado version is 6.5.2 or below and if your code uses RequestHandler.set_status() or tornado.web.HTTPError with user-supplied data in the 'reason' argument
Check Version:
python -c "import tornado; print(tornado.version)" or pip show tornado
Verify Fix Applied:
Verify Tornado version is 6.5.3 or higher and test that user input in status reason parameters is properly escaped
📡 Detection & Monitoring
Log Indicators:
- Unusual HTTP status reason phrases containing script tags or special characters
- Multiple 4xx/5xx errors with suspicious reason text
Network Indicators:
- HTTP responses with malformed headers containing unexpected content
- Error pages with embedded script tags in status messages
SIEM Query:
http.status_code:4* OR http.status_code:5* AND (http.reason_phrase:*<script* OR http.reason_phrase:*javascript:* OR http.reason_phrase:*%3Cscript*)