From 62e218291a9fb712678ec6219b2ee2f6625e7a0c Mon Sep 17 00:00:00 2001 From: Lumir Balhar Date: Tue, 12 Dec 2023 10:26:43 +0100 Subject: [PATCH] Security fix for CVE-2023-45803 Resolves: RHEL-16872 --- CVE-2023-45803.patch | 94 ++++++++++++++++++++++++++++++++++++++++++++ python-urllib3.spec | 13 +++++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 CVE-2023-45803.patch diff --git a/CVE-2023-45803.patch b/CVE-2023-45803.patch new file mode 100644 index 0000000..d17514b --- /dev/null +++ b/CVE-2023-45803.patch @@ -0,0 +1,94 @@ +From 6f6011442b255b6c135c294500cf4d404f594d8a Mon Sep 17 00:00:00 2001 +From: Lumir Balhar +Date: Tue, 12 Dec 2023 10:21:34 +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 34f2381..86fc900 100644 +--- a/src/urllib3/_collections.py ++++ b/src/urllib3/_collections.py +@@ -260,6 +260,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 f7a8f19..ad6303c 100644 +--- a/src/urllib3/connectionpool.py ++++ b/src/urllib3/connectionpool.py +@@ -32,6 +32,7 @@ from .connection import ( + HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, + HTTPException, BaseSSLError, + ) ++from ._collections import HTTPHeaderDict + from .request import RequestMethods + from .response import HTTPResponse + +@@ -679,7 +680,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 32bd973..37557f9 100644 +--- a/src/urllib3/poolmanager.py ++++ b/src/urllib3/poolmanager.py +@@ -3,7 +3,7 @@ import collections + import functools + import logging + +-from ._collections import RecentlyUsedContainer ++from ._collections import HTTPHeaderDict, RecentlyUsedContainer + from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool + from .connectionpool import port_by_scheme + from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +@@ -330,9 +330,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/python-urllib3.spec b/python-urllib3.spec index 6f673e7..14f0843 100644 --- a/python-urllib3.spec +++ b/python-urllib3.spec @@ -2,7 +2,7 @@ Name: python-%{srcname} Version: 1.24.2 -Release: 6%{?dist} +Release: 7%{?dist} Summary: Python HTTP library with thread-safe connection pooling and file post License: MIT @@ -42,6 +42,12 @@ Patch3: CVE-2020-26137.patch # Upstream fix: https://github.com/urllib3/urllib3/commit/01220354d389cd05474713f8c982d05c9b17aafb Patch4: 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 +Patch5: CVE-2023-45803.patch + %description Python HTTP module with connection pooling and file POST abilities. @@ -72,6 +78,7 @@ Python3 HTTP module with connection pooling and file POST abilities. %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 # Make sure that the RECENT_DATE value doesn't get too far behind what the current date is. # RECENT_DATE must not be older that 2 years from the build time, or else test_recent_date @@ -147,6 +154,10 @@ popd %changelog +* Tue Dec 12 2023 Lumír Balhar - 1.24.2-7 +- Security fix for CVE-2023-45803 +Resolves: RHEL-16872 + * Thu Oct 12 2023 Lumír Balhar - 1.24.2-6 - Security fix for CVE-2023-43804 Resolves: RHEL-11992