mirror of
git://git.openembedded.org/meta-openembedded
synced 2026-04-02 02:49:12 +00:00
python3-tornado: patch CVE-2025-67724
Details: https://nvd.nist.gov/vuln/detail/CVE-2025-67724 Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
parent
a0c05c9da8
commit
cfa04fece1
@ -0,0 +1,118 @@
|
||||
From 990054627cef3966a626162138164a77580d33ad 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-Status: Backport [https://github.com/tornadoweb/tornado/commit/9c163aebeaad9e6e7d28bac1f33580eb00b0e421]
|
||||
(cherry picked from commit 9c163aebeaad9e6e7d28bac1f33580eb00b0e421)
|
||||
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
|
||||
---
|
||||
tornado/test/web_test.py | 15 ++++++++++++++-
|
||||
tornado/web.py | 25 +++++++++++++++++++------
|
||||
2 files changed, 33 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py
|
||||
index fec66f39..801a80ed 100644
|
||||
--- a/tornado/test/web_test.py
|
||||
+++ b/tornado/test/web_test.py
|
||||
@@ -1712,7 +1712,7 @@ class StatusReasonTest(SimpleHandlerTestCase):
|
||||
class Handler(RequestHandler):
|
||||
def get(self):
|
||||
reason = self.request.arguments.get("reason", [])
|
||||
- self.set_status(
|
||||
+ raise HTTPError(
|
||||
int(self.get_argument("code")),
|
||||
reason=to_unicode(reason[0]) if reason else None,
|
||||
)
|
||||
@@ -1735,6 +1735,19 @@ class StatusReasonTest(SimpleHandlerTestCase):
|
||||
self.assertEqual(response.code, 682)
|
||||
self.assertEqual(response.reason, "Unknown")
|
||||
|
||||
+ def test_header_injection(self):
|
||||
+ response = self.fetch("/?code=200&reason=OK%0D%0AX-Injection:injected")
|
||||
+ self.assertEqual(response.code, 200)
|
||||
+ self.assertEqual(response.reason, "Unknown")
|
||||
+ self.assertNotIn("X-Injection", response.headers)
|
||||
+
|
||||
+ def test_reason_xss(self):
|
||||
+ response = self.fetch("/?code=400&reason=<script>alert(1)</script>")
|
||||
+ self.assertEqual(response.code, 400)
|
||||
+ self.assertEqual(response.reason, "Unknown")
|
||||
+ self.assertNotIn(b"script", response.body)
|
||||
+ self.assertIn(b"Unknown", response.body)
|
||||
+
|
||||
|
||||
class DateHeaderTest(SimpleHandlerTestCase):
|
||||
class Handler(RequestHandler):
|
||||
diff --git a/tornado/web.py b/tornado/web.py
|
||||
index 8ec5601b..8a740504 100644
|
||||
--- a/tornado/web.py
|
||||
+++ b/tornado/web.py
|
||||
@@ -350,8 +350,10 @@ class RequestHandler(object):
|
||||
|
||||
: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
|
||||
|
||||
@@ -360,6 +362,14 @@ class RequestHandler(object):
|
||||
"""
|
||||
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")
|
||||
@@ -1295,7 +1305,8 @@ class RequestHandler(object):
|
||||
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:
|
||||
@@ -1323,7 +1334,7 @@ class RequestHandler(object):
|
||||
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
|
||||
@@ -2469,9 +2480,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__(
|
||||
@ -8,7 +8,9 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57"
|
||||
|
||||
SRC_URI[sha256sum] = "92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b"
|
||||
|
||||
SRC_URI += "file://CVE-2025-47287.patch"
|
||||
SRC_URI += "file://CVE-2025-47287.patch \
|
||||
file://CVE-2025-67724.patch \
|
||||
"
|
||||
|
||||
inherit pypi python_setuptools_build_meta
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user