summaryrefslogtreecommitdiffstats
path: root/meta-python/recipes-devtools/python/python3-tornado
diff options
context:
space:
mode:
authorAnkur Tyagi <ankur.tyagi85@gmail.com>2026-01-15 02:00:50 +1300
committerAnuj Mittal <anuj.mittal@oss.qualcomm.com>2026-01-19 12:15:42 +0530
commitcfa04fece146248b8f0c3c522aa29f8e0f3a3cf3 (patch)
tree19b58eb1fad419a0c9b96c2139420d0070cf0378 /meta-python/recipes-devtools/python/python3-tornado
parenta0c05c9da8dda5147269a240ce0d69dbe4c63195 (diff)
downloadmeta-openembedded-cfa04fece146248b8f0c3c522aa29f8e0f3a3cf3.tar.gz
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>
Diffstat (limited to 'meta-python/recipes-devtools/python/python3-tornado')
-rw-r--r--meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67724.patch118
1 files changed, 118 insertions, 0 deletions
diff --git a/meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67724.patch b/meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67724.patch
new file mode 100644
index 0000000000..78cdae9666
--- /dev/null
+++ b/meta-python/recipes-devtools/python/python3-tornado/CVE-2025-67724.patch
@@ -0,0 +1,118 @@
1From 990054627cef3966a626162138164a77580d33ad Mon Sep 17 00:00:00 2001
2From: Ben Darnell <ben@bendarnell.com>
3Date: Wed, 10 Dec 2025 15:15:25 -0500
4Subject: [PATCH] web: Harden against invalid HTTP reason phrases
5
6We allow applications to set custom reason phrases for the HTTP status
7line (to support custom status codes), but if this were exposed to
8untrusted data it could be exploited in various ways. This commit
9guards against invalid reason phrases in both HTTP headers and in
10error pages.
11
12CVE: CVE-2025-67724
13Upstream-Status: Backport [https://github.com/tornadoweb/tornado/commit/9c163aebeaad9e6e7d28bac1f33580eb00b0e421]
14(cherry picked from commit 9c163aebeaad9e6e7d28bac1f33580eb00b0e421)
15Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
16---
17 tornado/test/web_test.py | 15 ++++++++++++++-
18 tornado/web.py | 25 +++++++++++++++++++------
19 2 files changed, 33 insertions(+), 7 deletions(-)
20
21diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py
22index fec66f39..801a80ed 100644
23--- a/tornado/test/web_test.py
24+++ b/tornado/test/web_test.py
25@@ -1712,7 +1712,7 @@ class StatusReasonTest(SimpleHandlerTestCase):
26 class Handler(RequestHandler):
27 def get(self):
28 reason = self.request.arguments.get("reason", [])
29- self.set_status(
30+ raise HTTPError(
31 int(self.get_argument("code")),
32 reason=to_unicode(reason[0]) if reason else None,
33 )
34@@ -1735,6 +1735,19 @@ class StatusReasonTest(SimpleHandlerTestCase):
35 self.assertEqual(response.code, 682)
36 self.assertEqual(response.reason, "Unknown")
37
38+ def test_header_injection(self):
39+ response = self.fetch("/?code=200&reason=OK%0D%0AX-Injection:injected")
40+ self.assertEqual(response.code, 200)
41+ self.assertEqual(response.reason, "Unknown")
42+ self.assertNotIn("X-Injection", response.headers)
43+
44+ def test_reason_xss(self):
45+ response = self.fetch("/?code=400&reason=<script>alert(1)</script>")
46+ self.assertEqual(response.code, 400)
47+ self.assertEqual(response.reason, "Unknown")
48+ self.assertNotIn(b"script", response.body)
49+ self.assertIn(b"Unknown", response.body)
50+
51
52 class DateHeaderTest(SimpleHandlerTestCase):
53 class Handler(RequestHandler):
54diff --git a/tornado/web.py b/tornado/web.py
55index 8ec5601b..8a740504 100644
56--- a/tornado/web.py
57+++ b/tornado/web.py
58@@ -350,8 +350,10 @@ class RequestHandler(object):
59
60 :arg int status_code: Response status code.
61 :arg str reason: Human-readable reason phrase describing the status
62- code. If ``None``, it will be filled in from
63- `http.client.responses` or "Unknown".
64+ code (for example, the "Not Found" in ``HTTP/1.1 404 Not Found``).
65+ Normally determined automatically from `http.client.responses`; this
66+ argument should only be used if you need to use a non-standard
67+ status code.
68
69 .. versionchanged:: 5.0
70
71@@ -360,6 +362,14 @@ class RequestHandler(object):
72 """
73 self._status_code = status_code
74 if reason is not None:
75+ if "<" in reason or not httputil._ABNF.reason_phrase.fullmatch(reason):
76+ # Logically this would be better as an exception, but this method
77+ # is called on error-handling paths that would need some refactoring
78+ # to tolerate internal errors cleanly.
79+ #
80+ # The check for "<" is a defense-in-depth against XSS attacks (we also
81+ # escape the reason when rendering error pages).
82+ reason = "Unknown"
83 self._reason = escape.native_str(reason)
84 else:
85 self._reason = httputil.responses.get(status_code, "Unknown")
86@@ -1295,7 +1305,8 @@ class RequestHandler(object):
87 reason = exception.reason
88 self.set_status(status_code, reason=reason)
89 try:
90- self.write_error(status_code, **kwargs)
91+ if status_code != 304:
92+ self.write_error(status_code, **kwargs)
93 except Exception:
94 app_log.error("Uncaught exception in write_error", exc_info=True)
95 if not self._finished:
96@@ -1323,7 +1334,7 @@ class RequestHandler(object):
97 self.finish(
98 "<html><title>%(code)d: %(message)s</title>"
99 "<body>%(code)d: %(message)s</body></html>"
100- % {"code": status_code, "message": self._reason}
101+ % {"code": status_code, "message": escape.xhtml_escape(self._reason)}
102 )
103
104 @property
105@@ -2469,9 +2480,11 @@ class HTTPError(Exception):
106 mode). May contain ``%s``-style placeholders, which will be filled
107 in with remaining positional parameters.
108 :arg str reason: Keyword-only argument. The HTTP "reason" phrase
109- to pass in the status line along with ``status_code``. Normally
110+ to pass in the status line along with ``status_code`` (for example,
111+ the "Not Found" in ``HTTP/1.1 404 Not Found``). Normally
112 determined automatically from ``status_code``, but can be used
113- to use a non-standard numeric code.
114+ to use a non-standard numeric code. This is not a general-purpose
115+ error message.
116 """
117
118 def __init__(