File CVE-2024-35195.patch of Package python-requests.33995
From c0813a2d910ea6b4f8438b91d315b8d181302356 Mon Sep 17 00:00:00 2001
From: Ian Stapleton Cordasco <graffatcolmingov@gmail.com>
Date: Sun, 3 Mar 2024 07:00:49 -0600
Subject: [PATCH] Use TLS settings in selecting connection pool
Previously, if someone made a request with `verify=False` then made a
request where they expected verification to be enabled to the same host,
they would potentially reuse a connection where TLS had not been
verified.
This fixes that issue.
---
src/requests/adapters.py | 58 +++++++++++++++++++++++++++++++++++++++-
tests/test_requests.py | 7 +++++
tox.ini | 2 +-
3 files changed, 65 insertions(+), 2 deletions(-)
Index: requests-2.25.1/requests/adapters.py
===================================================================
--- requests-2.25.1.orig/requests/adapters.py
+++ requests-2.25.1/requests/adapters.py
@@ -52,6 +52,27 @@ DEFAULT_RETRIES = 0
DEFAULT_POOL_TIMEOUT = None
+def _urllib3_request_context(request, verify):
+ host_params = {}
+ pool_kwargs = {}
+ parsed_request_url = urlparse(request.url)
+ scheme = parsed_request_url.scheme.lower()
+ port = parsed_request_url.port
+ cert_reqs = "CERT_REQUIRED"
+ if verify is False:
+ cert_reqs = "CERT_NONE"
+ if isinstance(verify, str):
+ pool_kwargs["ca_certs"] = verify
+ pool_kwargs["cert_reqs"] = cert_reqs
+ host_params = {
+ "scheme": scheme,
+ "host": parsed_request_url.hostname,
+ "port": port,
+ "pool_kwargs": pool_kwargs
+ }
+ return host_params
+
+
class BaseAdapter(object):
"""The Base Transport Adapter"""
@@ -289,6 +310,31 @@ class HTTPAdapter(BaseAdapter):
return response
+ def _get_connection(self, request, verify, proxies=None):
+ # Replace the existing get_connection without breaking things and
+ # ensure that TLS settings are considered when we interact with
+ # urllib3 HTTP Pools
+ proxy = select_proxy(request.url, proxies)
+ try:
+ host_params = _urllib3_request_context(request, verify)
+ except ValueError as e:
+ raise InvalidURL(e, request=request)
+ if proxy:
+ proxy = prepend_scheme_if_needed(proxy, "http")
+ proxy_url = parse_url(proxy)
+ if not proxy_url.host:
+ raise InvalidProxyURL(
+ "Please check proxy URL. It is malformed "
+ "and could be missing the host."
+ )
+ proxy_manager = self.proxy_manager_for(proxy)
+ conn = proxy_manager.connection_from_host(**host_params)
+ else:
+ # Only scheme should be lower case
+ conn = self.poolmanager.connection_from_host(**host_params)
+
+ return conn
+
def get_connection(self, url, proxies=None):
"""Returns a urllib3 connection for the given URL. This should not be
called from user code, and is only exposed for use when subclassing the
@@ -409,7 +455,7 @@ class HTTPAdapter(BaseAdapter):
"""
try:
- conn = self.get_connection(request.url, proxies)
+ conn = self._get_connection(request, verify, proxies)
except LocationValueError as e:
raise InvalidURL(e, request=request)
Index: requests-2.25.1/tests/test_requests.py
===================================================================
--- requests-2.25.1.orig/tests/test_requests.py
+++ requests-2.25.1/tests/test_requests.py
@@ -2398,6 +2398,13 @@ def test_urllib3_pool_connection_closed(
except ConnectionError as e:
assert u"Pool is closed." in str(e)
+ def test_different_connection_pool_for_tls_settings(self):
+ s = requests.Session()
+ r1 = s.get("https://invalid.badssl.com", verify=False)
+ assert r1.status_code == 421
+ with pytest.raises(requests.exceptions.SSLError):
+ s.get("https://invalid.badssl.com")
+
class TestPreparingURLs(object):
@pytest.mark.parametrize(