diff --git a/SOURCES/CVE-2023-43804.patch b/SOURCES/CVE-2023-43804.patch new file mode 100644 index 0000000..e685755 --- /dev/null +++ b/SOURCES/CVE-2023-43804.patch @@ -0,0 +1,53 @@ +From 5fe72b64a10e9cb5c5e2b9de46401b6c7bb226e9 Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Thu, 12 Oct 2023 14:27:36 +0200 +Subject: [PATCH] CVE-2023-43804 + +--- + src/urllib3/util/retry.py | 2 +- + test/test_retry.py | 2 +- + test/test_retry_deprecated.py | 2 +- + 3 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/urllib3/util/retry.py b/src/urllib3/util/retry.py +index 180e82b..63c02ee 100644 +--- a/src/urllib3/util/retry.py ++++ b/src/urllib3/util/retry.py +@@ -217,7 +217,7 @@ class Retry(object): + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + #: Default headers to be used for ``remove_headers_on_redirect`` +- DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Authorization"]) ++ DEFAULT_REMOVE_HEADERS_ON_REDIRECT = frozenset(["Cookie", "Authorization"]) + + #: Maximum backoff time. + BACKOFF_MAX = 120 +diff --git a/test/test_retry.py b/test/test_retry.py +index 3e71efe..e9270bb 100644 +--- a/test/test_retry.py ++++ b/test/test_retry.py +@@ -293,7 +293,7 @@ class TestRetry(object): + def test_retry_default_remove_headers_on_redirect(self): + retry = Retry() + +- assert list(retry.remove_headers_on_redirect) == ["authorization"] ++ assert retry.remove_headers_on_redirect == {"authorization", "cookie"} + + def test_retry_set_remove_headers_on_redirect(self): + retry = Retry(remove_headers_on_redirect=["X-API-Secret"]) +diff --git a/test/test_retry_deprecated.py b/test/test_retry_deprecated.py +index eafecc4..d18f94c 100644 +--- a/test/test_retry_deprecated.py ++++ b/test/test_retry_deprecated.py +@@ -295,7 +295,7 @@ class TestRetry(object): + def test_retry_default_remove_headers_on_redirect(self): + retry = Retry() + +- assert list(retry.remove_headers_on_redirect) == ["authorization"] ++ assert retry.remove_headers_on_redirect == {"authorization", "cookie"} + + def test_retry_set_remove_headers_on_redirect(self): + retry = Retry(remove_headers_on_redirect=["X-API-Secret"]) +-- +2.41.0 + diff --git a/SOURCES/CVE-2023-45803.patch b/SOURCES/CVE-2023-45803.patch new file mode 100644 index 0000000..a639836 --- /dev/null +++ b/SOURCES/CVE-2023-45803.patch @@ -0,0 +1,94 @@ +From d71ab28f104cac824c6036fa9b35cc2e2dd19bf8 Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Tue, 12 Dec 2023 11:06:20 +0100 +Subject: [PATCH] Security fix for CVE-2023-45803 + +--- + src/urllib3/_collections.py | 18 ++++++++++++++++++ + src/urllib3/connectionpool.py | 5 +++++ + src/urllib3/poolmanager.py | 7 +++++-- + 3 files changed, 28 insertions(+), 2 deletions(-) + +diff --git a/src/urllib3/_collections.py b/src/urllib3/_collections.py +index da9857e..bceb845 100644 +--- a/src/urllib3/_collections.py ++++ b/src/urllib3/_collections.py +@@ -268,6 +268,24 @@ class HTTPHeaderDict(MutableMapping): + else: + return vals[1:] + ++ def _prepare_for_method_change(self): ++ """ ++ Remove content-specific header fields before changing the request ++ method to GET or HEAD according to RFC 9110, Section 15.4. ++ """ ++ content_specific_headers = [ ++ "Content-Encoding", ++ "Content-Language", ++ "Content-Location", ++ "Content-Type", ++ "Content-Length", ++ "Digest", ++ "Last-Modified", ++ ] ++ for header in content_specific_headers: ++ self.discard(header) ++ return self ++ + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist +diff --git a/src/urllib3/connectionpool.py b/src/urllib3/connectionpool.py +index 4018321..8f9ebb5 100644 +--- a/src/urllib3/connectionpool.py ++++ b/src/urllib3/connectionpool.py +@@ -36,6 +36,7 @@ from .exceptions import ( + from .packages import six + from .packages.six.moves import queue + from .packages.ssl_match_hostname import CertificateError ++from ._collections import HTTPHeaderDict + from .request import RequestMethods + from .response import HTTPResponse + from .util.connection import is_connection_dropped +@@ -800,7 +801,11 @@ class HTTPConnectionPool(ConnectionPool, RequestMethods): + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: ++ # Change the method according to RFC 9110, Section 15.4.4. + method = "GET" ++ # And lose the body not to transfer anything sensitive. ++ body = None ++ headers = HTTPHeaderDict(headers)._prepare_for_method_change() + + try: + retries = retries.increment(method, url, response=response, _pool=self) +diff --git a/src/urllib3/poolmanager.py b/src/urllib3/poolmanager.py +index 3a31a28..7d4c22c 100644 +--- a/src/urllib3/poolmanager.py ++++ b/src/urllib3/poolmanager.py +@@ -4,7 +4,7 @@ import collections + import functools + import logging + +-from ._collections import RecentlyUsedContainer ++from ._collections import HTTPHeaderDict, RecentlyUsedContainer + from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool, port_by_scheme + from .exceptions import ( + LocationValueError, +@@ -381,9 +381,12 @@ class PoolManager(RequestMethods): + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + +- # RFC 7231, Section 6.4.4 + if response.status == 303: ++ # Change the method according to RFC 9110, Section 15.4.4. + method = "GET" ++ # And lose the body not to transfer anything sensitive. ++ kw["body"] = None ++ kw["headers"] = HTTPHeaderDict(kw["headers"])._prepare_for_method_change() + + retries = kw.get("retries") + if not isinstance(retries, Retry): +-- +2.43.0 + diff --git a/SPECS/python-urllib3.spec b/SPECS/python-urllib3.spec index 8e0e11d..f39293f 100644 --- a/SPECS/python-urllib3.spec +++ b/SPECS/python-urllib3.spec @@ -6,7 +6,7 @@ Name: python-%{srcname} Version: 1.26.5 -Release: 3%{?dist} +Release: 3%{?dist}.1 Summary: Python HTTP library with thread-safe connection pooling and file post License: MIT @@ -16,6 +16,22 @@ Source0: %{url}/archive/%{version}/%{srcname}-%{version}.tar.gz Source1: ssl_match_hostname_py3.py BuildArch: noarch +# CVE-2023-43804 +# Added the `Cookie` header to the list of headers to strip from +# requests when redirecting to a different host. As before, different headers +# can be set via `Retry.remove_headers_on_redirect`. +# Tests backported only partially as we don't use the whole part of +# testing with dummyserver. +# Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=2242493 +# Upstream fix: https://github.com/urllib3/urllib3/commit/01220354d389cd05474713f8c982d05c9b17aafb +Patch1: CVE-2023-43804.patch + +# CVE-2023-45803 +# Remove HTTP request body when request method is changed. +# Tracking bug: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2023-45803 +# Upstream fix: https://github.com/urllib3/urllib3/commit/4e98d57809dacab1cbe625fddeec1a290c478ea9 +Patch2: CVE-2023-45803.patch + %description Python HTTP module with connection pooling and file POST abilities. @@ -118,6 +134,10 @@ ln -s %{python3_sitelib}/__pycache__/six.cpython-%{python3_version_nodots}.pyc \ %changelog +* Mon Dec 18 2023 Lumír Balhar - 1.26.5-3.1 +- Security fix for CVE-2023-45803 and CVE-2023-43804 +Resolves: RHEL-16873 RHEL-19704 + * Tue Feb 08 2022 Tomáš Hrnčiar - 1.26.5-3 - Add automatically generated Obsoletes tag with the python39- prefix for smoother upgrade from RHEL8