CVE-2025-67724
Python vulnerability analysis and mitigation

Overview

CVE-2025-67724 is a header injection and Cross-Site Scripting (XSS) vulnerability in the Tornado Python web framework affecting versions 6.5.2 and below. The flaw exists in the reason argument used by RequestHandler.set_status and tornado.web.HTTPError, where untrusted input is passed unescaped into HTTP headers or the default HTML error page. It was disclosed on December 11–12, 2025, and fixed in version 6.5.3. The CVSS v3.1 base score is 5.4 (Moderate) per the GitHub Security Advisory, or 6.1 (Medium) per NVD scoring (GitHub Advisory, Red Hat Bugzilla).

Technical details

The root cause is improper neutralization of user-controlled input in two contexts: HTTP response headers (CWE-644) and HTML error page output (CWE-79). The reason argument to RequestHandler.set_status and tornado.web.HTTPError was designed for custom HTTP status reason phrases (e.g., the "Not Found" in HTTP/1.1 404 Not Found), but in vulnerable versions it was inserted into the HTTP status line and error page HTML without sanitization or validation. An attacker who can influence the reason argument — for example, via a query parameter that a developer passes directly to HTTPError — can inject CRLF sequences (\r\n) to add arbitrary HTTP headers, or inject HTML/JavaScript into the default error page rendered to users. The fix in commit 9c163ae adds validation that rejects reason phrases containing < or characters outside the valid HTTP reason-phrase character set, and applies xhtml_escape() when rendering the reason in error pages (GitHub Commit, GitHub Advisory).

Impact

Successful exploitation enables two attack classes: reflected XSS in the default Tornado error page (allowing arbitrary JavaScript execution in a victim's browser, enabling session token theft, CSRF escalation, or UI spoofing), and HTTP header injection (allowing an attacker to inject arbitrary response headers, potentially enabling cache poisoning, response splitting, or redirect attacks). The scope is limited to applications that explicitly pass untrusted input into the reason argument; applications using static string literals for reason are not affected. There is no direct impact on availability or server-side confidentiality (GitHub Advisory).

Exploitability

No public proof-of-concept exploit code has been published, and there is no evidence of in-the-wild exploitation as of the time of disclosure (Feedly). The vulnerability is not listed in the CISA Known Exploited Vulnerabilities (KEV) catalog. The EPSS score is approximately 0.028% (0.000280), indicating a very low probability of exploitation in the near term. Exploitation requires user interaction (a victim must visit or be directed to the crafted error page) and depends on the application reflecting untrusted data into the reason argument, which is an uncommon but not rare developer pattern.

Exploitation steps

  1. Identify a vulnerable target: Find a Tornado-based web application running version 6.5.2 or earlier where a developer passes user-controlled input (e.g., a query parameter) into the reason argument of HTTPError or set_status.
  2. Craft a malicious payload: For XSS, construct a payload such as <script>alert(document.cookie)</script> to be injected as the reason phrase. For header injection, craft a CRLF payload like OK\r\nX-Injected-Header: malicious.
  3. Trigger the error response: Send an HTTP request to the vulnerable endpoint with the malicious reason phrase embedded in the controlled parameter (e.g., GET /error?code=400&reason=<script>alert(1)</script>).
  4. Deliver to victim (XSS): Craft a URL containing the malicious payload and socially engineer a victim into clicking it. When the Tornado server renders the default error page, the unescaped reason phrase executes the injected JavaScript in the victim's browser.
  5. Achieve objective: Depending on the payload, steal session cookies, perform CSRF actions, redirect the user, or inject arbitrary HTTP headers into the response for cache poisoning or response splitting attacks (GitHub Advisory, GitHub Commit).

Indicators of compromise

  • Network: HTTP requests to Tornado endpoints with URL-encoded CRLF sequences (%0D%0A) or HTML/script tags (<script>, %3Cscript%3E) in query parameters that are passed to error-handling paths.
  • Logs: Tornado access logs showing requests with unusual characters in parameters mapped to reason arguments; HTTP responses containing unexpected headers not set by the application.
  • Application Behavior: Default Tornado error pages (e.g., 400: <injected content>) rendering unexpected HTML or JavaScript content; HTTP responses with injected headers such as X-Injected-Header or Set-Cookie appearing in error responses.

Mitigation and workarounds

Upgrade Tornado to version 6.5.3 or later, which validates reason phrases against the HTTP specification and applies HTML escaping when rendering error pages (GitHub Release). As a workaround without upgrading, avoid passing any untrusted or user-controlled data into the reason argument of RequestHandler.set_status or tornado.web.HTTPError; the argument is intended for static string literals tied to non-standard status codes. For general-purpose error messages, use the log_message argument of HTTPError instead. Additionally, deploying a Content Security Policy (CSP) header can reduce the impact of any XSS that does occur. IBM has also released advisories for affected products (Data Virtualization on IBM Software Hub, IBM Db2 on Cloud Pak for Data) that bundle Tornado (IBM Advisory).

Community reactions

The vulnerability was reported by security researchers Finder16 and Cheshire1225 and disclosed by Tornado maintainer bdarnell via a GitHub Security Advisory on December 11, 2025 (GitHub Advisory). Red Hat tracked the issue via Bugzilla and assessed it as medium severity (Red Hat Bugzilla). Multiple Linux distributions including Ubuntu, Debian, openSUSE, Amazon Linux 2, and Mageia issued security advisories and updated their packaged versions of python-tornado. IBM published advisories for several Cloud Pak for Data products that include Tornado as a dependency.

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-61539CRITICAL10
  • Python logoPython
  • xinference
NoYesAug 21, 2026
CVE-2026-49360HIGH7.8
  • Python logoPython
  • recce
NoYesAug 21, 2026
CVE-2026-68508HIGH7.8
  • Python logoPython
  • hydra-core
NoYesAug 21, 2026
CVE-2026-43980MEDIUM6.3
  • Python logoPython
  • malla
NoNoAug 21, 2026
CVE-2026-55468MEDIUM4.3
  • Python logoPython
  • wagtail
NoYesAug 24, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management