CVE-2025-67724

5.4 MEDIUM

📋 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

Products:
  • Tornado web framework
Versions: 6.5.2 and below
Operating Systems: All platforms running Python
Default Config Vulnerable: ⚠️ Yes
Notes: Only vulnerable if applications use the 'reason' argument in RequestHandler.set_status() or tornado.web.HTTPError with untrusted user input.

📦 What is this software?

⚠️ 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.

🌐 Internet-Facing: HIGH
🏢 Internal Only: MEDIUM

🎯 Exploit Status

Public PoC: ✅ No
Weaponized: LIKELY
Unauthenticated Exploit: ⚠️ Yes
Complexity: LOW

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

all

Implement strict input validation and output encoding for any data passed to the 'reason' argument in HTTP status methods

Disable custom reason phrases

all

Avoid 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*)

🔗 References

📤 Share & Export