Package: release.debian.org Severity: normal Tags: bookworm X-Debbugs-Cc: python-torn...@packages.debian.org Control: affects -1 + src:python-tornado User: release.debian....@packages.debian.org Usertags: pu
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 [ Reason ] This upload intends to fix the vulnerabilities CVE-2024-52804 and CVE-2023-28370. CVE-2023-28370 allows a remote unauthenticated attacker to redirect a user to an arbitrary web site and conduct a phishing attack by having a user access a specially crafted URL. CVE-2024-52804 can lead to excessive CPU consumption when parsing maliciously-crafted cookie headers. [ Impact ] Users of Debian Bookworm will continue to be vulnerable to the mentioned issues if the update is not approved. [ Tests ] For both issues, tests have been added or adjusted. The tests are run during build and via autopkgtest and ran successfully. [ Risks ] The changes are quite simple. However, regressions are always possible. The fact that the tests are successful reduce the risk of regressions. [ Checklist ] [x] *all* changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in (old)stable [x] the issue is verified as fixed in unstable [ Changes ] For CVE-2023-28370, the fix simply leads to a refusal of attempts to redirect to URLs that could be misinterpreted. For CVE-2024-52804, a quadratic algorithm, originally copied from Python 3.5, is replaced with the implementation copied from the Python 3.13 standard library. [ Other info ] All patches contain links to the original reports and commits. -----BEGIN PGP SIGNATURE----- iQIzBAEBCgAdFiEEvu1N7VVEpMA+KD3HS80FZ8KW0F0FAmdzRCwACgkQS80FZ8KW 0F2UPhAAsIbmA/9NykDhNg0Pu7ZFkRZK3gIhX58B4vsjMQp6oRAUgYYaINQPsrIj YtEkjIkkil2be8oBip8zIzAI/FdB5BZ8cUz/BHCUC7wIjznsdMbsL/yHhWvZ6KXe THXypEr1qPueCWIhcJE7LKuoYekmlRsHS8DzlN/Q9IeqObmHz0OQudPruylBd+Y8 uvqNZ1MLiXNTQGBK6FrjiL2CXxOwt52nSVd1xLHzJgPFPHL6Yytu6rp2iq0HKvnV T0IoRtOMk2CA2uMx2Wh4fUIbgDRJPZ34TdbJW8Kuq4Rqwq1+v5tmOkRNGGyVpcUg GMp6FH9JPPgk4nit/zC8l5ZH5vs9WU93G8//B3kfFty2XbbKTK8mGaRnbQe9Fss/ rr5JtGVxLc7ozdnlCcf6rmQhbo+ZkeBNKKgkSR34iHKK4SNgTIE5Juh1Tvd6K0ZU 5HmxEbSX8mATYflyupnFvtLaHJ0piSObsWkRL5jlTwf0BSntjdhBWTWIo9IuWQcY U2WW/xXnYRr2BPMIAYrVctd6jnjYzpE4zn7cMUaEpUmEqTATAvUo932KMT7ueraj Ymy7f6nJcpqq6LiQ9FJ8NV3700OwFUKA94juxaq13OW3lkEwpFnEjlRyDV7BrFdL SiyEQolqoyZvUMl0JTyruDJEPjT1LZx2/xSkqKzfOR7IpVdy1jo= =qDcm -----END PGP SIGNATURE-----
diff -Nru python-tornado-6.2.0/debian/changelog python-tornado-6.2.0/debian/changelog --- python-tornado-6.2.0/debian/changelog 2022-11-20 13:24:11.000000000 +0100 +++ python-tornado-6.2.0/debian/changelog 2024-12-31 01:53:59.000000000 +0100 @@ -1,3 +1,21 @@ +python-tornado (6.2.0-3+deb12u1) bookworm; urgency=medium + + * Non-maintainer upload by the Debian LTS team. + * d/patches/CVE-2024-52804.patch: Fix CVE-2024-52804 (closes: #1088112). + - The algorithm used for parsing HTTP cookies in Tornado versions prior to + 6.4.2 sometimes has quadratic complexity, leading to excessive CPU + consumption when parsing maliciously-crafted cookie headers. This + parsing occurs in the event loop thread and may block the processing of + other requests. + * d/patches/CVE-2023-28370-1.patch, + d/patches/CVE-2023-28370-2.patch: Fix CVE-2023-28370 (closes: #1036875). + - Open redirect vulnerability in Tornado versions 6.3.1 and earlier allows + a remote unauthenticated attacker to redirect a user to an arbitrary web + site and conduct a phishing attack by having user access a specially + crafted URL. + + -- Daniel Leidert <dleid...@debian.org> Tue, 31 Dec 2024 01:53:59 +0100 + python-tornado (6.2.0-3) unstable; urgency=medium [ Debian Janitor ] diff -Nru python-tornado-6.2.0/debian/gbp.conf python-tornado-6.2.0/debian/gbp.conf --- python-tornado-6.2.0/debian/gbp.conf 1970-01-01 01:00:00.000000000 +0100 +++ python-tornado-6.2.0/debian/gbp.conf 2024-12-31 01:53:59.000000000 +0100 @@ -0,0 +1,4 @@ +[DEFAULT] +upstream-branch = upstream +debian-branch = debian/bookworm +pristine-tar = True diff -Nru python-tornado-6.2.0/debian/patches/CVE-2023-28370-1.patch python-tornado-6.2.0/debian/patches/CVE-2023-28370-1.patch --- python-tornado-6.2.0/debian/patches/CVE-2023-28370-1.patch 1970-01-01 01:00:00.000000000 +0100 +++ python-tornado-6.2.0/debian/patches/CVE-2023-28370-1.patch 2024-12-31 01:53:59.000000000 +0100 @@ -0,0 +1,41 @@ +From: Ben Darnell <b...@bendarnell.com> +Date: Sat, 13 May 2023 20:58:52 -0400 +Subject: web: Fix an open redirect in StaticFileHandler + +Under some configurations the default_filename redirect could be exploited +to redirect to an attacker-controlled site. This change refuses to redirect +to URLs that could be misinterpreted. + +A test case for the specific vulnerable configuration will follow after the +patch has been available. + +Reviewed-By: Daniel Leidert <dleid...@debian.org> +Origin: https://github.com/tornadoweb/tornado/pull/3266 +Bug: https://github.com/advisories/GHSA-hj3f-6gcp-jg8j +Bug-Debian: https://bugs.debian.org/1036875 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2023-28370 +Bug-Freexian-Security: https://deb.freexian.com/extended-lts/tracker/CVE-2023-28370 +--- + tornado/web.py | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/tornado/web.py b/tornado/web.py +index cd6a81b..05b571e 100644 +--- a/tornado/web.py ++++ b/tornado/web.py +@@ -2806,6 +2806,15 @@ class StaticFileHandler(RequestHandler): + # but there is some prefix to the path that was already + # trimmed by the routing + if not self.request.path.endswith("/"): ++ if self.request.path.startswith("//"): ++ # A redirect with two initial slashes is a "protocol-relative" URL. ++ # This means the next path segment is treated as a hostname instead ++ # of a part of the path, making this effectively an open redirect. ++ # Reject paths starting with two slashes to prevent this. ++ # This is only reachable under certain configurations. ++ raise HTTPError( ++ 403, "cannot redirect path with two initial slashes" ++ ) + self.redirect(self.request.path + "/", permanent=True) + return None + absolute_path = os.path.join(absolute_path, self.default_filename) diff -Nru python-tornado-6.2.0/debian/patches/CVE-2023-28370-2.patch python-tornado-6.2.0/debian/patches/CVE-2023-28370-2.patch --- python-tornado-6.2.0/debian/patches/CVE-2023-28370-2.patch 1970-01-01 01:00:00.000000000 +0100 +++ python-tornado-6.2.0/debian/patches/CVE-2023-28370-2.patch 2024-12-31 01:53:59.000000000 +0100 @@ -0,0 +1,63 @@ +From: Ben Darnell <b...@bendarnell.com> +Date: Tue, 6 Jun 2023 22:48:05 -0400 +Subject: test: Add test for open redirect fixed in 6.3.2 + +Reviewed-By: Daniel Leidert <dleid...@debian.org> +Origin: https://github.com/tornadoweb/tornado/pull/3276 +Bug: https://github.com/advisories/GHSA-hj3f-6gcp-jg8j +Bug-Debian: https://bugs.debian.org/1036875 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2023-28370 +Bug-Freexian-Security: https://deb.freexian.com/extended-lts/tracker/CVE-2023-28370 +--- + tornado/test/web_test.py | 31 ++++++++++++++++++++++++++++++- + 1 file changed, 30 insertions(+), 1 deletion(-) + +diff --git a/tornado/test/web_test.py b/tornado/test/web_test.py +index 396ba6d..7e33033 100644 +--- a/tornado/test/web_test.py ++++ b/tornado/test/web_test.py +@@ -1426,6 +1426,35 @@ class StaticDefaultFilenameTest(WebTestCase): + self.assertTrue(response.headers["Location"].endswith("/static/dir/")) + + ++class StaticDefaultFilenameRootTest(WebTestCase): ++ def get_app_kwargs(self): ++ return dict( ++ static_path=os.path.abspath(relpath("static")), ++ static_handler_args=dict(default_filename="index.html"), ++ static_url_prefix="/", ++ ) ++ ++ def get_handlers(self): ++ return [] ++ ++ def get_http_client(self): ++ # simple_httpclient only: curl doesn't let you send a request starting ++ # with two slashes. ++ return SimpleAsyncHTTPClient() ++ ++ def test_no_open_redirect(self): ++ # This test verifies that the open redirect that affected some configurations ++ # prior to Tornado 6.3.2 is no longer possible. The vulnerability required ++ # a static_url_prefix of "/" and a default_filename (any value) to be set. ++ # The absolute server-side path to the static directory must also be known. ++ with ExpectLog(gen_log, ".*cannot redirect path with two initial slashes"): ++ response = self.fetch( ++ f"//evil.com/../{os.path.dirname(__file__)}/static/dir", ++ follow_redirects=False, ++ ) ++ self.assertEqual(response.code, 403) ++ ++ + class StaticFileWithPathTest(WebTestCase): + def get_app_kwargs(self): + return dict( +@@ -2837,7 +2866,7 @@ class XSRFTest(SimpleHandlerTestCase): + body=b"", + headers=dict( + {"X-Xsrftoken": self.xsrf_token}, # type: ignore +- **self.cookie_headers() ++ **self.cookie_headers(), + ), + ) + self.assertEqual(response.code, 200) diff -Nru python-tornado-6.2.0/debian/patches/CVE-2024-52804.patch python-tornado-6.2.0/debian/patches/CVE-2024-52804.patch --- python-tornado-6.2.0/debian/patches/CVE-2024-52804.patch 1970-01-01 01:00:00.000000000 +0100 +++ python-tornado-6.2.0/debian/patches/CVE-2024-52804.patch 2024-12-31 01:53:59.000000000 +0100 @@ -0,0 +1,144 @@ +From: Ben Darnell <b...@bendarnell.com> +Date: Thu, 21 Nov 2024 14:48:05 -0500 +Subject: httputil: Fix quadratic performance of cookie parsing + +Maliciously-crafted cookies can cause Tornado to +spend an unreasonable amount of CPU time and block +the event loop. + +This change replaces the quadratic algorithm with +a more efficient one. The implementation is copied +from the Python 3.13 standard library (the +previous one was from Python 3.5). + +Fixes CVE-2024-52804 +See CVE-2024-7592 for a similar vulnerability in cpython. + +Thanks to github.com/kexinoh for the report. + +Reviewed-By: Daniel Leidert <dleid...@debian.org> +Origin: https://github.com/tornadoweb/tornado/commit/d5ba4a1695fbf7c6a3e54313262639b198291533.patch +Bug: https://github.com/tornadoweb/tornado/security/advisories/GHSA-8w49-h785-mj3c +Bug-Debian: https://bugs.debian.org/1088112 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2024-52804 +Bug-Freexian-Security: https://deb.freexian.com/extended-lts/tracker/CVE-2024-52804 +--- + tornado/httputil.py | 38 ++++++++++------------------------- + tornado/test/httputil_test.py | 46 +++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 56 insertions(+), 28 deletions(-) + +diff --git a/tornado/httputil.py b/tornado/httputil.py +index 9c341d4..f74eced 100644 +--- a/tornado/httputil.py ++++ b/tornado/httputil.py +@@ -1053,15 +1053,20 @@ def qs_to_qsl(qs: Dict[str, List[AnyStr]]) -> Iterable[Tuple[str, AnyStr]]: + yield (k, v) + + +-_OctalPatt = re.compile(r"\\[0-3][0-7][0-7]") +-_QuotePatt = re.compile(r"[\\].") +-_nulljoin = "".join ++_unquote_sub = re.compile(r"\\(?:([0-3][0-7][0-7])|(.))").sub ++ ++ ++def _unquote_replace(m: re.Match) -> str: ++ if m[1]: ++ return chr(int(m[1], 8)) ++ else: ++ return m[2] + + + def _unquote_cookie(s: str) -> str: + """Handle double quotes and escaping in cookie values. + +- This method is copied verbatim from the Python 3.5 standard ++ This method is copied verbatim from the Python 3.13 standard + library (http.cookies._unquote) so we don't have to depend on + non-public interfaces. + """ +@@ -1082,30 +1087,7 @@ def _unquote_cookie(s: str) -> str: + # \012 --> \n + # \" --> " + # +- i = 0 +- n = len(s) +- res = [] +- while 0 <= i < n: +- o_match = _OctalPatt.search(s, i) +- q_match = _QuotePatt.search(s, i) +- if not o_match and not q_match: # Neither matched +- res.append(s[i:]) +- break +- # else: +- j = k = -1 +- if o_match: +- j = o_match.start(0) +- if q_match: +- k = q_match.start(0) +- if q_match and (not o_match or k < j): # QuotePatt matched +- res.append(s[i:k]) +- res.append(s[k + 1]) +- i = k + 2 +- else: # OctalPatt matched +- res.append(s[i:j]) +- res.append(chr(int(s[j + 1 : j + 4], 8))) +- i = j + 4 +- return _nulljoin(res) ++ return _unquote_sub(_unquote_replace, s) + + + def parse_cookie(cookie: str) -> Dict[str, str]: +diff --git a/tornado/test/httputil_test.py b/tornado/test/httputil_test.py +index 0fad403..25faf66 100644 +--- a/tornado/test/httputil_test.py ++++ b/tornado/test/httputil_test.py +@@ -519,3 +519,49 @@ class ParseCookieTest(unittest.TestCase): + self.assertEqual( + parse_cookie(" = b ; ; = ; c = ; "), {"": "b", "c": ""} + ) ++ ++ def test_unquote(self): ++ # Copied from ++ # https://github.com/python/cpython/blob/dc7a2b6522ec7af41282bc34f405bee9b306d611/Lib/test/test_http_cookies.py#L62 ++ cases = [ ++ (r'a="b=\""', 'b="'), ++ (r'a="b=\\"', "b=\\"), ++ (r'a="b=\="', "b=="), ++ (r'a="b=\n"', "b=n"), ++ (r'a="b=\042"', 'b="'), ++ (r'a="b=\134"', "b=\\"), ++ (r'a="b=\377"', "b=\xff"), ++ (r'a="b=\400"', "b=400"), ++ (r'a="b=\42"', "b=42"), ++ (r'a="b=\\042"', "b=\\042"), ++ (r'a="b=\\134"', "b=\\134"), ++ (r'a="b=\\\""', 'b=\\"'), ++ (r'a="b=\\\042"', 'b=\\"'), ++ (r'a="b=\134\""', 'b=\\"'), ++ (r'a="b=\134\042"', 'b=\\"'), ++ ] ++ for encoded, decoded in cases: ++ with self.subTest(encoded): ++ c = parse_cookie(encoded) ++ self.assertEqual(c["a"], decoded) ++ ++ def test_unquote_large(self): ++ # Adapted from ++ # https://github.com/python/cpython/blob/dc7a2b6522ec7af41282bc34f405bee9b306d611/Lib/test/test_http_cookies.py#L87 ++ # Modified from that test because we handle semicolons differently from the stdlib. ++ # ++ # This is a performance regression test: prior to improvements in Tornado 6.4.2, this test ++ # would take over a minute with n= 100k. Now it runs in tens of milliseconds. ++ n = 100000 ++ for encoded in r"\\", r"\134": ++ with self.subTest(encoded): ++ start = time.time() ++ data = 'a="b=' + encoded * n + '"' ++ value = parse_cookie(data)["a"] ++ end = time.time() ++ self.assertEqual(value[:3], "b=\\") ++ self.assertEqual(value[-3:], "\\\\\\") ++ self.assertEqual(len(value), n + 2) ++ ++ # Very loose performance check to avoid false positives ++ self.assertLess(end - start, 1, "Test took too long") diff -Nru python-tornado-6.2.0/debian/patches/series python-tornado-6.2.0/debian/patches/series --- python-tornado-6.2.0/debian/patches/series 2022-11-20 13:24:11.000000000 +0100 +++ python-tornado-6.2.0/debian/patches/series 2024-12-31 01:53:59.000000000 +0100 @@ -4,3 +4,6 @@ 0006-Use-local-objects.inv-for-intersphinx-mapping.patch 0007-Higher-test_gc-timeout.patch ignore-py310-deprecation-warnings.patch +CVE-2024-52804.patch +CVE-2023-28370-1.patch +CVE-2023-28370-2.patch