mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-09-10 16:24:17 -09:00
Fixes the following vulnerabilities:
- CVE-2025-67724:
Tornado is a Python web framework and asynchronous networking library.
In versions 6.5.2 and below, the supplied reason phrase is used
unescaped in HTTP headers (where it could be used for header
injection) or in HTML in the default error page (where it could be
used for XSS) and can be exploited by passing untrusted or malicious
data into the reason argument. Used by both RequestHandler.set_status
and tornado.web.HTTPError, the argument is designed to allow
applications to pass custom "reason" phrases (the "Not Found" in
HTTP/1.1 404 Not Found) to the HTTP status line (mainly for non-
standard status codes). This issue is fixed in version 6.5.3.
For more information, see:
- https://www.cve.org/CVERecord?id=CVE-2025-67724
- 9c163aebea
- CVE-2025-67725:
Tornado is a Python web framework and asynchronous networking library.
In versions 6.5.2 and below, a single maliciously crafted HTTP request
can block the server's event loop for an extended period, caused by
the HTTPHeaders.add method. The function accumulates values using
string concatenation when the same header name is repeated, causing a
Denial of Service (DoS). Due to Python string immutability, each
concatenation copies the entire string, resulting in O(n²) time
complexity. The severity can vary from high if max_header_size has
been increased from its default, to low if it has its default value of
64KB. This issue is fixed in version 6.5.3.
For more information, see:
- https://www.cve.org/CVERecord?id=CVE-2025-67725
- 771472cfda
- CVE-2025-67726:
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.
For more information, see:
- https://www.cve.org/CVERecord?id=CVE-2025-67726
- 771472cfda
(cherry picked from commit e59cc42d2f)
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
84 lines
3.9 KiB
Diff
84 lines
3.9 KiB
Diff
From 9c163aebeaad9e6e7d28bac1f33580eb00b0e421 Mon Sep 17 00:00:00 2001
|
|
From: Ben Darnell <ben@bendarnell.com>
|
|
Date: Wed, 10 Dec 2025 15:15:25 -0500
|
|
Subject: [PATCH] web: Harden against invalid HTTP reason phrases
|
|
|
|
We allow applications to set custom reason phrases for the HTTP status
|
|
line (to support custom status codes), but if this were exposed to
|
|
untrusted data it could be exploited in various ways. This commit
|
|
guards against invalid reason phrases in both HTTP headers and in
|
|
error pages.
|
|
|
|
CVE: CVE-2025-67724
|
|
Upstream: https://github.com/tornadoweb/tornado/commit/9c163aebeaad9e6e7d28bac1f33580eb00b0e421
|
|
Signed-off-by: Thomas Perale <thomas.perale@mind.be>
|
|
---
|
|
tornado/web.py | 25 +++++++++++++++++++------
|
|
1 files changed, 19 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/tornado/web.py b/tornado/web.py
|
|
index 2f702d6480..2351afdbe2 100644
|
|
--- a/tornado/web.py
|
|
+++ b/tornado/web.py
|
|
@@ -359,8 +359,10 @@ def set_status(self, status_code: int, reason: Optional[str] = None) -> None:
|
|
|
|
:arg int status_code: Response status code.
|
|
:arg str reason: Human-readable reason phrase describing the status
|
|
- code. If ``None``, it will be filled in from
|
|
- `http.client.responses` or "Unknown".
|
|
+ code (for example, the "Not Found" in ``HTTP/1.1 404 Not Found``).
|
|
+ Normally determined automatically from `http.client.responses`; this
|
|
+ argument should only be used if you need to use a non-standard
|
|
+ status code.
|
|
|
|
.. versionchanged:: 5.0
|
|
|
|
@@ -369,6 +371,14 @@ def set_status(self, status_code: int, reason: Optional[str] = None) -> None:
|
|
"""
|
|
self._status_code = status_code
|
|
if reason is not None:
|
|
+ if "<" in reason or not httputil._ABNF.reason_phrase.fullmatch(reason):
|
|
+ # Logically this would be better as an exception, but this method
|
|
+ # is called on error-handling paths that would need some refactoring
|
|
+ # to tolerate internal errors cleanly.
|
|
+ #
|
|
+ # The check for "<" is a defense-in-depth against XSS attacks (we also
|
|
+ # escape the reason when rendering error pages).
|
|
+ reason = "Unknown"
|
|
self._reason = escape.native_str(reason)
|
|
else:
|
|
self._reason = httputil.responses.get(status_code, "Unknown")
|
|
@@ -1345,7 +1355,8 @@ def send_error(self, status_code: int = 500, **kwargs: Any) -> None:
|
|
reason = exception.reason
|
|
self.set_status(status_code, reason=reason)
|
|
try:
|
|
- self.write_error(status_code, **kwargs)
|
|
+ if status_code != 304:
|
|
+ self.write_error(status_code, **kwargs)
|
|
except Exception:
|
|
app_log.error("Uncaught exception in write_error", exc_info=True)
|
|
if not self._finished:
|
|
@@ -1373,7 +1384,7 @@ def write_error(self, status_code: int, **kwargs: Any) -> None:
|
|
self.finish(
|
|
"<html><title>%(code)d: %(message)s</title>"
|
|
"<body>%(code)d: %(message)s</body></html>"
|
|
- % {"code": status_code, "message": self._reason}
|
|
+ % {"code": status_code, "message": escape.xhtml_escape(self._reason)}
|
|
)
|
|
|
|
@property
|
|
@@ -2520,9 +2531,11 @@ class HTTPError(Exception):
|
|
mode). May contain ``%s``-style placeholders, which will be filled
|
|
in with remaining positional parameters.
|
|
:arg str reason: Keyword-only argument. The HTTP "reason" phrase
|
|
- to pass in the status line along with ``status_code``. Normally
|
|
+ to pass in the status line along with ``status_code`` (for example,
|
|
+ the "Not Found" in ``HTTP/1.1 404 Not Found``). Normally
|
|
determined automatically from ``status_code``, but can be used
|
|
- to use a non-standard numeric code.
|
|
+ to use a non-standard numeric code. This is not a general-purpose
|
|
+ error message.
|
|
"""
|
|
|
|
def __init__(
|