diff --git a/CVE-2026-21441.patch b/CVE-2026-21441.patch new file mode 100644 index 0000000..13d5976 --- /dev/null +++ b/CVE-2026-21441.patch @@ -0,0 +1,65 @@ +From e078b83c2dbd7fddc88d9a698479b91e78eae964 Mon Sep 17 00:00:00 2001 +From: Illia Volochii +Date: Wed, 7 Jan 2026 18:07:30 +0200 +Subject: [PATCH] Merge commit from fork + +* Stop decoding response content during redirects needlessly + +* Rename the new query parameter + +* Add a changelog entry +--- + src/urllib3/response.py | 6 +++++- + test/with_dummyserver/test_connectionpool.py | 19 +++++++++++++++++++ + 2 files changed, 24 insertions(+), 1 deletion(-) + +diff --git a/src/urllib3/response.py b/src/urllib3/response.py +index 37936f93..fbbccdbd 100644 +--- a/src/urllib3/response.py ++++ b/src/urllib3/response.py +@@ -610,7 +610,11 @@ class HTTPResponse(BaseHTTPResponse): + Unread data in the HTTPResponse connection blocks the connection from being released back to the pool. + """ + try: +- self.read() ++ self.read( ++ # Do not spend resources decoding the content unless ++ # decoding has already been initiated. ++ decode_content=self._has_decoded_content, ++ ) + except (HTTPError, OSError, BaseSSLError, HTTPException): + pass + +diff --git a/test/with_dummyserver/test_connectionpool.py b/test/with_dummyserver/test_connectionpool.py +index c0f4d9d5..5e58c971 100644 +--- a/test/with_dummyserver/test_connectionpool.py ++++ b/test/with_dummyserver/test_connectionpool.py +@@ -480,6 +480,25 @@ class TestConnectionPool(HTTPDummyServerTestCase): + assert r.status == 200 + assert r.data == b"Dummy server!" + ++ @mock.patch("urllib3.response.GzipDecoder.decompress") ++ def test_no_decoding_with_redirect_when_preload_disabled( ++ self, gzip_decompress: mock.MagicMock ++ ) -> None: ++ """ ++ Test that urllib3 does not attempt to decode a gzipped redirect ++ response when `preload_content` is set to `False`. ++ """ ++ with HTTPConnectionPool(self.host, self.port) as pool: ++ # Three requests are expected: two redirects and one final / 200 OK. ++ response = pool.request( ++ "GET", ++ "/redirect", ++ fields={"target": "/redirect?compressed=true", "compressed": "true"}, ++ preload_content=False, ++ ) ++ assert response.status == 200 ++ gzip_decompress.assert_not_called() ++ + def test_303_redirect_makes_request_lose_body(self) -> None: + with HTTPConnectionPool(self.host, self.port) as pool: + response = pool.request( +-- +2.52.0 + diff --git a/python-urllib3.changes b/python-urllib3.changes index 6453640..962672e 100644 --- a/python-urllib3.changes +++ b/python-urllib3.changes @@ -1,3 +1,10 @@ +------------------------------------------------------------------- +Tue Jan 13 09:58:43 UTC 2026 - John Paul Adrian Glaubitz + +- Add CVE-2026-21441.patch to fix excessive resource consumption + during decompression of data in HTTP redirect responses + (bsc#1256331, CVE-2026-21441) + ------------------------------------------------------------------- Wed Jul 2 05:03:53 UTC 2025 - Steve Kowalik diff --git a/python-urllib3.spec b/python-urllib3.spec index 283d63b..c1f7f73 100644 --- a/python-urllib3.spec +++ b/python-urllib3.spec @@ -38,6 +38,9 @@ Patch1: openssl-3.2.patch Patch2: CVE-2024-37891.patch # PATCH-FIX-UPSTREAM CVE-2025-50181 gh#urllib3/urllib3@f05b1329126d, bsc#1244925 Patch3: CVE-2025-50181-poolmanager-redirects.patch +# PATCH-FIX-UPSTREAM https://github.com/urllib3/urllib3/commit/8864ac407bba8607950025e0979c4c69bc7abc7b +# Stop decoding response content during redirects needlessly (CVE-2026-21441) +Patch4: CVE-2026-21441.patch BuildRequires: %{python_module base >= 3.7} BuildRequires: %{python_module hatchling} BuildRequires: %{python_module pip}