diff --git a/CVE-2025-67725_CVE-2025-67726.patch b/CVE-2025-67725_CVE-2025-67726.patch new file mode 100644 index 0000000000000000000000000000000000000000..9acc5d49f21f746034e744445bc554c91a032b04 --- /dev/null +++ b/CVE-2025-67725_CVE-2025-67726.patch @@ -0,0 +1,99 @@ +From e5d3f9bb48f7936dc0d48ed48632737820190ca7 Mon Sep 17 00:00:00 2001 +From: wangguochun +Date: Mon, 15 Dec 2025 20:28:52 +0800 +Subject: [PATCH] httputil: Fix quadratic behavior in + _parseparam + +Prior to this change, _parseparam had O(n^2) behavior when parsing +certain inputs, which could be a DoS vector. This change adapts +logic from the equivalent function in the python standard library +in https://github.com/python/cpython/pull/136072/files +ref:https://github.com/tornadoweb/tornado/commit/771472cfdaeebc0d89a9cc46e249f8891a6b29cd +--- + tornado/httputil.py | 30 ++++++++++++++++++++++-------- + tornado/test/httputil_test.py | 23 +++++++++++++++++++++++ + 2 files changed, 45 insertions(+), 8 deletions(-) + +diff --git a/tornado/httputil.py b/tornado/httputil.py +index ceff735..2e4840b 100644 +--- a/tornado/httputil.py ++++ b/tornado/httputil.py +@@ -860,19 +860,33 @@ def parse_response_start_line(line): + # combinations of semicolons and double quotes. + # It has also been modified to support valueless parameters as seen in + # websocket extension negotiations. +- ++# ++# _parseparam has been further modified with the logic from ++# https://github.com/python/cpython/pull/136072/files ++# to avoid quadratic behavior when parsing semicolons in quoted strings. ++# ++# TODO: See if we can switch to email.message.Message for this functionality. ++# This is the suggested replacement for the cgi.py module now that cgi has ++# been removed from recent versions of Python. We need to verify that ++# the email module is consistent with our existing behavior (and all relevant ++# RFCs for multipart/form-data) before making this change. + + def _parseparam(s): +- while s[:1] == ';': +- s = s[1:] +- end = s.find(';') +- while end > 0 and (s.count('"', 0, end) - s.count('\\"', 0, end)) % 2: +- end = s.find(';', end + 1) ++ start = 0 ++ while s.find(";", start) == start: ++ start += 1 ++ end = s.find(";", start) ++ ind, diff = start, 0 ++ while end > 0: ++ diff += s.count('"', ind, end) - s.count('\\"', ind, end) ++ if diff % 2 == 0: ++ break ++ end, ind = ind, s.find(";", end + 1) + if end < 0: + end = len(s) +- f = s[:end] ++ f = s[start:end] + yield f.strip() +- s = s[end:] ++ start = end + + + def _parse_header(line): +diff --git a/tornado/test/httputil_test.py b/tornado/test/httputil_test.py +index 5c064dd..38b762d 100644 +--- a/tornado/test/httputil_test.py ++++ b/tornado/test/httputil_test.py +@@ -257,6 +257,29 @@ Foo + self.assertEqual(file["filename"], "ab.txt") + self.assertEqual(file["body"], b"Foo") + ++ def test_disposition_param_linear_performance(self): ++ # This is a regression test for performance of parsing parameters ++ # to the content-disposition header, specifically for semicolons within ++ # quoted strings. ++ def f(n): ++ start = time.time() ++ message = ( ++ b"--1234\r\nContent-Disposition: form-data; " ++ + b'x="' ++ + b";" * n ++ + b'"; ' ++ + b'name="files"; filename="a.txt"\r\n\r\nFoo\r\n--1234--\r\n' ++ ) ++ args = {} ++ files = {} ++ parse_multipart_form_data(b"1234", message, args, files) ++ return time.time() - start ++ ++ d1 = f(1000) ++ d2 = f(10000) ++ if d2 / d1 > 20: ++ self.fail("Disposition param parsing is not linear: d1={} vs d2={}".format(d1, d2)) ++ + + class HTTPHeadersTest(unittest.TestCase): + def test_multi_line(self): +-- +2.25.1 + diff --git a/python-tornado.spec b/python-tornado.spec index a239a556faf581e594443fbb00f32b9c43c93349..cbe2ab4d684c52a95a73d615f3a5b8cc072abb78 100644 --- a/python-tornado.spec +++ b/python-tornado.spec @@ -1,6 +1,6 @@ Name: python-tornado Version: 5.0.2 -Release: 10 +Release: 11 Summary: a Python web framework and asynchronous networking library License: ASL 2.0 URL: http://www.tornadoweb.org @@ -9,6 +9,7 @@ Patch0: fix-erroneous-deprecation-warnings.patch Patch1: CVE-2023-28370.patch Patch2: CVE-2024-52804.patch Patch3: CVE-2025-47287-for-5.0.2.patch +Patch4: CVE-2025-67725_CVE-2025-67726.patch BuildRequires: gcc python2-devel python2-singledispatch python3-devel @@ -65,6 +66,9 @@ and other applications that require a long-lived connection to each user. %{python3_sitearch}/* %changelog +* Mon Dec 15 2025 wangguochun - 5.0.2-11 +- Fix CVE-2025-67726 and CVE-2025-67725 + * Fri Jun 27 2025 xieyanlong - 5.0.2-10 - Fix CVE-2025-47287