Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python-requests: patch CVE-2024-35195. #9238

Merged
merged 6 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions SPECS/python-requests/CVE-2024-35195.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
diff --git a/requests/adapters.py b/requests/adapters.py
liulanze marked this conversation as resolved.
Show resolved Hide resolved
index fe22ff450..4fa5163de 100644
--- a/requests/adapters.py
+++ b/requests/adapters.py
@@ -10,6 +10,7 @@ and maintain connections.

import os.path
import socket
+import typing

from urllib3.poolmanager import PoolManager, proxy_from_url
from urllib3.response import HTTPResponse
@@ -47,12 +48,39 @@ except ImportError:
def SOCKSProxyManager(*args, **kwargs):
raise InvalidSchema("Missing dependencies for SOCKS support.")

+
+if typing.TYPE_CHECKING:
+ from .models import PreparedRequest
+
+
DEFAULT_POOLBLOCK = False
DEFAULT_POOLSIZE = 10
DEFAULT_RETRIES = 0
DEFAULT_POOL_TIMEOUT = None


+def _urllib3_request_context(
+ request: "PreparedRequest", verify: "bool | str | None"
+) -> "(typing.Dict[str, typing.Any], typing.Dict[str, typing.Any])":
+ 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,
+ }
+ return host_params, pool_kwargs
+
+
class BaseAdapter(object):
"""The Base Transport Adapter"""

@@ -290,6 +318,35 @@ 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, pool_kwargs = _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, pool_kwargs=pool_kwargs
+ )
+ else:
+ # Only scheme should be lower case
+ conn = self.poolmanager.connection_from_host(
+ **host_params, pool_kwargs=pool_kwargs
+ )
+
+ 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
@@ -410,7 +467,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)

diff --git a/tests/test_requests.py b/tests/test_requests.py
index 29b3aca84..13cbabcee 100644
--- a/tests/test_requests.py
+++ b/tests/test_requests.py
@@ -2587,3 +2607,10 @@ class TestPreparingURLs(object):
r = requests.get(httpbin('bytes/20'))
with pytest.raises(requests.exceptions.JSONDecodeError):
r.json()
+
+ 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")
diff --git a/tox.ini b/tox.ini
index 5e3d53774..d4c25a8b4 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,7 +7,7 @@ extras =
security
socks
commands =
- pytest tests
+ pytest {posargs:tests}

[testenv:default]

6 changes: 5 additions & 1 deletion SPECS/python-requests/python-requests.spec
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
Summary: Awesome Python HTTP Library That's Actually Usable
Name: python-requests
Version: 2.27.1
Release: 6%{?dist}
Release: 7%{?dist}
License: ASL 2.0
Vendor: Microsoft Corporation
Distribution: Mariner
Group: Development/Languages/Python
URL: http://python-requests.org
Source0: https://github.com/requests/requests/archive/v%{version}/requests-v%{version}.tar.gz#/requests-%{version}.tar.gz
Patch0: CVE-2023-32681.patch
Patch1: CVE-2024-35195.patch
BuildArch: noarch

%description
Expand Down Expand Up @@ -72,6 +73,9 @@ LANG=en_US.UTF-8 tox -e py%{python3_version_nodots}
%{python3_sitelib}/*

%changelog
* Tue May 28 2024 Lanze Liu <[email protected]> - 2.27.1-7
- Add patch for CVE-2024-35195

* Mon Jun 12 2023 Suresh Thelkar <[email protected]> - 2.27.1-6
- Add patch for CVE-2023-32681

Expand Down
Loading