From ccaf773b3ff30aa488aec81e5dc065f88b004072 Mon Sep 17 00:00:00 2001 From: lingsheng <860373352@qq.com> Date: Wed, 19 Nov 2025 15:38:14 +0800 Subject: [PATCH] fix CVE-2024-35195 --- backport-0001-CVE-2024-35195.patch | 99 ++++++++++++++++++++++++ backport-0002-CVE-2024-35195.patch | 77 +++++++++++++++++++ backport-0003-CVE-2024-35195.patch | 96 ++++++++++++++++++++++++ backport-0004-CVE-2024-35195.patch | 66 ++++++++++++++++ backport-0005-CVE-2024-35195.patch | 116 +++++++++++++++++++++++++++++ backport-0006-CVE-2024-35195.patch | 49 ++++++++++++ backport-0007-CVE-2024-35195.patch | 63 ++++++++++++++++ backport-0008-CVE-2024-35195.patch | 107 ++++++++++++++++++++++++++ python-requests.spec | 13 +++- 9 files changed, 685 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2024-35195.patch create mode 100644 backport-0002-CVE-2024-35195.patch create mode 100644 backport-0003-CVE-2024-35195.patch create mode 100644 backport-0004-CVE-2024-35195.patch create mode 100644 backport-0005-CVE-2024-35195.patch create mode 100644 backport-0006-CVE-2024-35195.patch create mode 100644 backport-0007-CVE-2024-35195.patch create mode 100644 backport-0008-CVE-2024-35195.patch diff --git a/backport-0001-CVE-2024-35195.patch b/backport-0001-CVE-2024-35195.patch new file mode 100644 index 0000000..976aa24 --- /dev/null +++ b/backport-0001-CVE-2024-35195.patch @@ -0,0 +1,99 @@ +From c0813a2d910ea6b4f8438b91d315b8d181302356 Mon Sep 17 00:00:00 2001 +From: Ian Stapleton Cordasco +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. + +Reference:https://github.com/psf/requests/commit/c0813a2d910ea6b4f8438b91d315b8d181302356 +Conflict:Adapt context,remove typing related codes and tox.ini,remove dict unpacking to adapt python2,remove test cases incompatible with python2 +--- + requests/adapters.py | 53 +++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 52 insertions(+), 1 deletion(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index fa4d9b3..c78bdcd 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -52,6 +52,26 @@ 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, ++ } ++ return host_params, pool_kwargs ++ ++ + class BaseAdapter(object): + """The Base Transport Adapter""" + +@@ -289,6 +309,37 @@ 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=host_params["host"], port=host_params["port"], ++ scheme=host_params["scheme"], pool_kwargs=pool_kwargs ++ ) ++ else: ++ # Only scheme should be lower case ++ conn = self.poolmanager.connection_from_host( ++ host=host_params["host"], port=host_params["port"], ++ scheme=host_params["scheme"], 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 +@@ -409,7 +460,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) + +-- +2.33.0 + diff --git a/backport-0002-CVE-2024-35195.patch b/backport-0002-CVE-2024-35195.patch new file mode 100644 index 0000000..d8a4eae --- /dev/null +++ b/backport-0002-CVE-2024-35195.patch @@ -0,0 +1,77 @@ +From a94e9b5308ffcc3d2913ab873e9810a6601a67da Mon Sep 17 00:00:00 2001 +From: Ian Stapleton Cordasco +Date: Wed, 13 Mar 2024 15:58:45 -0500 +Subject: [PATCH] Add local TLS server + +This also adds certificates for testing purposes and files to make it +easy to generate/regenerate them. + +This also replaces an existing test of how we utilize our pool manager +such that we don't connect to badssl.com + +Finally, this adds additional context parameters for our pool manager to +account for mTLS certificates used by clients to authenticate to a +server. + +Reference:https://github.com/psf/requests/commit/a94e9b5308ffcc3d2913ab873e9810a6601a67da +Conflict:Adapt context,remove test cases incompatible with python2 +--- + requests/adapters.py | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index c78bdcd..6c8c006 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -52,7 +52,7 @@ DEFAULT_RETRIES = 0 + DEFAULT_POOL_TIMEOUT = None + + +-def _urllib3_request_context(request, verify): ++def _urllib3_request_context(request, verify, client_cert): + host_params = {} + pool_kwargs = {} + parsed_request_url = urlparse(request.url) +@@ -64,6 +64,14 @@ def _urllib3_request_context(request, verify): + if isinstance(verify, str): + pool_kwargs["ca_certs"] = verify + pool_kwargs["cert_reqs"] = cert_reqs ++ if client_cert is not None: ++ if isinstance(client_cert, tuple) and len(client_cert) == 2: ++ pool_kwargs["cert_file"] = client_cert[0] ++ pool_kwargs["key_file"] = client_cert[1] ++ else: ++ # According to our docs, we allow users to specify just the client ++ # cert path ++ pool_kwargs["cert_file"] = client_cert + host_params = { + "scheme": scheme, + "host": parsed_request_url.hostname, +@@ -309,13 +317,13 @@ class HTTPAdapter(BaseAdapter): + + return response + +- def _get_connection(self, request, verify, proxies=None): ++ def _get_connection(self, request, verify, proxies=None, cert=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) ++ host_params, pool_kwargs = _urllib3_request_context(request, verify, cert) + except ValueError as e: + raise InvalidURL(e, request=request) + if proxy: +@@ -460,7 +468,7 @@ class HTTPAdapter(BaseAdapter): + """ + + try: +- conn = self._get_connection(request, verify, proxies) ++ conn = self._get_connection(request, verify, proxies=proxies, cert=cert) + except LocationValueError as e: + raise InvalidURL(e, request=request) + +-- +2.33.0 + diff --git a/backport-0003-CVE-2024-35195.patch b/backport-0003-CVE-2024-35195.patch new file mode 100644 index 0000000..5d367a2 --- /dev/null +++ b/backport-0003-CVE-2024-35195.patch @@ -0,0 +1,96 @@ +From 9a40d1277807f0a4f26c9a37eea8ec90faa8aadc Mon Sep 17 00:00:00 2001 +From: agubelu +Date: Wed, 15 May 2024 22:07:26 +0200 +Subject: [PATCH] Avoid reloading root certificates to improve concurrent + performance (#6667) + +Reference:https://github.com/psf/requests/commit/9a40d1277807f0a4f26c9a37eea8ec90faa8aadc +Conflict:Adapt context +--- + requests/adapters.py | 44 ++++++++++++++++++++++++++++---------------- + 1 file changed, 28 insertions(+), 16 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index db800e5..e74d96c 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -16,6 +16,7 @@ from urllib3.response import HTTPResponse + from urllib3.util import parse_url + from urllib3.util import Timeout as TimeoutSauce + from urllib3.util.retry import Retry ++from urllib3.util.ssl_ import create_urllib3_context + from urllib3.exceptions import ClosedPoolError + from urllib3.exceptions import ConnectTimeoutError + from urllib3.exceptions import HTTPError as _HTTPError +@@ -51,6 +52,11 @@ DEFAULT_POOLSIZE = 10 + DEFAULT_RETRIES = 0 + DEFAULT_POOL_TIMEOUT = None + ++_preloaded_ssl_context = create_urllib3_context() ++_preloaded_ssl_context.load_verify_locations( ++ extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) ++) ++ + + def _urllib3_request_context(request, verify, client_cert): + host_params = {} +@@ -61,8 +67,13 @@ def _urllib3_request_context(request, verify, client_cert): + cert_reqs = "CERT_REQUIRED" + if verify is False: + cert_reqs = "CERT_NONE" +- if isinstance(verify, str): +- pool_kwargs["ca_certs"] = verify ++ elif verify is True: ++ pool_kwargs["ssl_context"] = _preloaded_ssl_context ++ elif isinstance(verify, str): ++ if not os.path.isdir(verify): ++ pool_kwargs["ca_certs"] = verify ++ else: ++ pool_kwargs["ca_cert_dir"] = verify + pool_kwargs["cert_reqs"] = cert_reqs + if client_cert is not None: + if isinstance(client_cert, tuple) and len(client_cert) == 2: +@@ -242,25 +253,26 @@ class HTTPAdapter(BaseAdapter): + """ + if url.lower().startswith('https') and verify: + +- cert_loc = None ++ conn.cert_reqs = "CERT_REQUIRED" + +- # Allow self-specified cert location. ++ # Only load the CA certificates if 'verify' is a string indicating the CA bundle to use. ++ # Otherwise, if verify is a boolean, we don't load anything since ++ # the connection will be using a context with the default certificates already loaded, ++ # and this avoids a call to the slow load_verify_locations() + if verify is not True: ++ # `verify` must be a str with a path then + cert_loc = verify + +- if not cert_loc: +- cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) +- +- if not cert_loc or not os.path.exists(cert_loc): +- raise IOError("Could not find a suitable TLS CA certificate bundle, " +- "invalid path: {}".format(cert_loc)) +- +- conn.cert_reqs = 'CERT_REQUIRED' ++ if not os.path.exists(cert_loc): ++ raise OSError( ++ "Could not find a suitable TLS CA certificate bundle, " ++ "invalid path: {}".format(cert_loc) ++ ) + +- if not os.path.isdir(cert_loc): +- conn.ca_certs = cert_loc +- else: +- conn.ca_cert_dir = cert_loc ++ if not os.path.isdir(cert_loc): ++ conn.ca_certs = cert_loc ++ else: ++ conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None +-- +2.33.0 + diff --git a/backport-0004-CVE-2024-35195.patch b/backport-0004-CVE-2024-35195.patch new file mode 100644 index 0000000..ba32666 --- /dev/null +++ b/backport-0004-CVE-2024-35195.patch @@ -0,0 +1,66 @@ +From aa1461b68aa73e2f6ec0e78c8853b635c76fd099 Mon Sep 17 00:00:00 2001 +From: Nate Prewitt +Date: Tue, 21 May 2024 05:40:52 -0700 +Subject: [PATCH] Move _get_connection to get_connection_with_tls_context + +Reference:https://github.com/psf/requests/commit/aa1461b68aa73e2f6ec0e78c8853b635c76fd099 +Conflict:no +--- + requests/adapters.py | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index e74d96c..a1eee4f 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -329,10 +329,20 @@ class HTTPAdapter(BaseAdapter): + + return response + +- def _get_connection(self, request, verify, proxies=None, cert=None): +- # Replace the existing get_connection without breaking things and +- # ensure that TLS settings are considered when we interact with +- # urllib3 HTTP Pools ++ def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None): ++ """Returns a urllib3 connection for the given request and TLS settings. ++ This should not be called from user code, and is only exposed for use ++ when subclassing the :class:`HTTPAdapter `. ++ ++ :param request: The :class:`PreparedRequest ` object ++ to be sent over the connection. ++ :param verify: Either a boolean, in which case it controls whether ++ we verify the server's TLS certificate, or a string, in which case it ++ must be a path to a CA bundle to use. ++ :param proxies: (optional) The proxies dictionary to apply to the request. ++ :param cert: (optional) Any user-provided SSL certificate to be trusted. ++ :rtype: urllib3.ConnectionPool ++ """ + proxy = select_proxy(request.url, proxies) + try: + host_params, pool_kwargs = _urllib3_request_context(request, verify, cert) +@@ -359,7 +369,10 @@ class HTTPAdapter(BaseAdapter): + return conn + + def get_connection(self, url, proxies=None): +- """Returns a urllib3 connection for the given URL. This should not be ++ """DEPRECATED: Users should move to `get_connection_with_tls_context` ++ for all subclasses of HTTPAdapter using Requests>=2.32.2. ++ ++ 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 + :class:`HTTPAdapter `. + +@@ -478,7 +491,9 @@ class HTTPAdapter(BaseAdapter): + """ + + try: +- conn = self._get_connection(request, verify, proxies=proxies, cert=cert) ++ conn = self.get_connection_with_tls_context( ++ request, verify, proxies=proxies, cert=cert ++ ) + except LocationValueError as e: + raise InvalidURL(e, request=request) + +-- +2.33.0 + diff --git a/backport-0005-CVE-2024-35195.patch b/backport-0005-CVE-2024-35195.patch new file mode 100644 index 0000000..d58ac0a --- /dev/null +++ b/backport-0005-CVE-2024-35195.patch @@ -0,0 +1,116 @@ +From a62a2d35d918baa8e793f7aa4fb41527644dfca5 Mon Sep 17 00:00:00 2001 +From: Ian Stapleton Cordasco +Date: Wed, 22 May 2024 06:51:48 -0500 +Subject: [PATCH] Allow for overriding of specific pool key params + +This re-enables the use case of providing a custom SSLContext via a +Transport Adapter as broken in #6655 and reported in #6715 + +Closes #6715 + +Reference:https://github.com/psf/requests/commit/a62a2d35d918baa8e793f7aa4fb41527644dfca5 +Conflict:no +--- + requests/adapters.py | 78 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 69 insertions(+), 9 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index a1eee4f..770400d 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -329,23 +329,83 @@ class HTTPAdapter(BaseAdapter): + + return response + ++ def build_connection_pool_key_attributes(self, request, verify, cert=None): ++ """Build the PoolKey attributes used by urllib3 to return a connection. ++ ++ This looks at the PreparedRequest, the user-specified verify value, ++ and the value of the cert parameter to determine what PoolKey values ++ to use to select a connection from a given urllib3 Connection Pool. ++ ++ The SSL related pool key arguments are not consistently set. As of ++ this writing, use the following to determine what keys may be in that ++ dictionary: ++ ++ * If ``verify`` is ``True``, ``"ssl_context"`` will be set and will be the ++ default Requests SSL Context ++ * If ``verify`` is ``False``, ``"ssl_context"`` will not be set but ++ ``"cert_reqs"`` will be set ++ * If ``verify`` is a string, (i.e., it is a user-specified trust bundle) ++ ``"ca_certs"`` will be set if the string is not a directory recognized ++ by :py:func:`os.path.isdir`, otherwise ``"ca_certs_dir"`` will be ++ set. ++ * If ``"cert"`` is specified, ``"cert_file"`` will always be set. If ++ ``"cert"`` is a tuple with a second item, ``"key_file"`` will also ++ be present ++ ++ To override these settings, one may subclass this class, call this ++ method and use the above logic to change parameters as desired. For ++ example, if one wishes to use a custom :py:class:`ssl.SSLContext` one ++ must both set ``"ssl_context"`` and based on what else they require, ++ alter the other keys to ensure the desired behaviour. ++ ++ :param request: ++ The PreparedReqest being sent over the connection. ++ :type request: ++ :class:`~requests.models.PreparedRequest` ++ :param verify: ++ Either a boolean, in which case it controls whether ++ we verify the server's TLS certificate, or a string, in which case it ++ must be a path to a CA bundle to use. ++ :param cert: ++ (optional) Any user-provided SSL certificate for client ++ authentication (a.k.a., mTLS). This may be a string (i.e., just ++ the path to a file which holds both certificate and key) or a ++ tuple of length 2 with the certificate file path and key file ++ path. ++ :returns: ++ A tuple of two dictionaries. The first is the "host parameters" ++ portion of the Pool Key including scheme, hostname, and port. The ++ second is a dictionary of SSLContext related parameters. ++ """ ++ return _urllib3_request_context(request, verify, cert) ++ + def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None): + """Returns a urllib3 connection for the given request and TLS settings. + This should not be called from user code, and is only exposed for use + when subclassing the :class:`HTTPAdapter `. + +- :param request: The :class:`PreparedRequest ` object +- to be sent over the connection. +- :param verify: Either a boolean, in which case it controls whether +- we verify the server's TLS certificate, or a string, in which case it +- must be a path to a CA bundle to use. +- :param proxies: (optional) The proxies dictionary to apply to the request. +- :param cert: (optional) Any user-provided SSL certificate to be trusted. +- :rtype: urllib3.ConnectionPool ++ :param request: ++ The :class:`PreparedRequest ` object to be sent ++ over the connection. ++ :param verify: ++ Either a boolean, in which case it controls whether we verify the ++ server's TLS certificate, or a string, in which case it must be a ++ path to a CA bundle to use. ++ :param proxies: ++ (optional) The proxies dictionary to apply to the request. ++ :param cert: ++ (optional) Any user-provided SSL certificate to be used for client ++ authentication (a.k.a., mTLS). ++ :rtype: ++ urllib3.ConnectionPool + """ + proxy = select_proxy(request.url, proxies) + try: +- host_params, pool_kwargs = _urllib3_request_context(request, verify, cert) ++ host_params, pool_kwargs = self.build_connection_pool_key_attributes( ++ request, ++ verify, ++ cert, ++ ) + except ValueError as e: + raise InvalidURL(e, request=request) + if proxy: +-- +2.33.0 + diff --git a/backport-0006-CVE-2024-35195.patch b/backport-0006-CVE-2024-35195.patch new file mode 100644 index 0000000..cc0f09d --- /dev/null +++ b/backport-0006-CVE-2024-35195.patch @@ -0,0 +1,49 @@ +From b1d73ddb509a3a2d3e10744e85f9cdebdbde90f0 Mon Sep 17 00:00:00 2001 +From: Nate Prewitt +Date: Fri, 24 May 2024 09:00:52 -0700 +Subject: [PATCH] Don't use default SSLContext with custom poolmanager kwargs + +Reference:https://github.com/psf/requests/commit/b1d73ddb509a3a2d3e10744e85f9cdebdbde90f0 +Conflict:no +--- + requests/adapters.py | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index 770400d..7bbeee1 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -58,16 +58,19 @@ _preloaded_ssl_context.load_verify_locations( + ) + + +-def _urllib3_request_context(request, verify, client_cert): ++def _urllib3_request_context(request, verify, client_cert, poolmanager): + host_params = {} + pool_kwargs = {} + parsed_request_url = urlparse(request.url) + scheme = parsed_request_url.scheme.lower() + port = parsed_request_url.port ++ poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {}) ++ has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context") ++ + cert_reqs = "CERT_REQUIRED" + if verify is False: + cert_reqs = "CERT_NONE" +- elif verify is True: ++ elif verify is True and not has_poolmanager_ssl_context: + pool_kwargs["ssl_context"] = _preloaded_ssl_context + elif isinstance(verify, str): + if not os.path.isdir(verify): +@@ -377,7 +380,7 @@ class HTTPAdapter(BaseAdapter): + portion of the Pool Key including scheme, hostname, and port. The + second is a dictionary of SSLContext related parameters. + """ +- return _urllib3_request_context(request, verify, cert) ++ return _urllib3_request_context(request, verify, cert, self.poolmanager) + + def get_connection_with_tls_context(self, request, verify, proxies=None, cert=None): + """Returns a urllib3 connection for the given request and TLS settings. +-- +2.33.0 + diff --git a/backport-0007-CVE-2024-35195.patch b/backport-0007-CVE-2024-35195.patch new file mode 100644 index 0000000..fdcd696 --- /dev/null +++ b/backport-0007-CVE-2024-35195.patch @@ -0,0 +1,63 @@ +From e18879932287c2bf4bcee4ddf6ccb8a69b6fc656 Mon Sep 17 00:00:00 2001 +From: Nate Prewitt +Date: Wed, 29 May 2024 08:23:39 -0700 +Subject: [PATCH] Don't create default SSLContext if ssl module isn't present + (#6724) + +Reference:https://github.com/psf/requests/commit/e18879932287c2bf4bcee4ddf6ccb8a69b6fc656 +Conflict:no +--- + requests/adapters.py | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index 7bbeee1..29fe7ae 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -52,10 +52,18 @@ DEFAULT_POOLSIZE = 10 + DEFAULT_RETRIES = 0 + DEFAULT_POOL_TIMEOUT = None + +-_preloaded_ssl_context = create_urllib3_context() +-_preloaded_ssl_context.load_verify_locations( +- extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) +-) ++ ++try: ++ import ssl # noqa: F401 ++ ++ _preloaded_ssl_context = create_urllib3_context() ++ _preloaded_ssl_context.load_verify_locations( ++ extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) ++ ) ++except ImportError: ++ # Bypass default SSLContext creation when Python ++ # interpreter isn't built with the ssl module. ++ _preloaded_ssl_context = None + + + def _urllib3_request_context(request, verify, client_cert, poolmanager): +@@ -64,13 +72,19 @@ def _urllib3_request_context(request, verify, client_cert, poolmanager): + parsed_request_url = urlparse(request.url) + scheme = parsed_request_url.scheme.lower() + port = parsed_request_url.port ++ ++ # Determine if we have and should use our default SSLContext ++ # to optimize performance on standard requests. + poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {}) + has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context") ++ should_use_default_ssl_context = ( ++ _preloaded_ssl_context is not None and not has_poolmanager_ssl_context ++ ) + + cert_reqs = "CERT_REQUIRED" + if verify is False: + cert_reqs = "CERT_NONE" +- elif verify is True and not has_poolmanager_ssl_context: ++ elif verify is True and should_use_default_ssl_context: + pool_kwargs["ssl_context"] = _preloaded_ssl_context + elif isinstance(verify, str): + if not os.path.isdir(verify): +-- +2.33.0 + diff --git a/backport-0008-CVE-2024-35195.patch b/backport-0008-CVE-2024-35195.patch new file mode 100644 index 0000000..364a36c --- /dev/null +++ b/backport-0008-CVE-2024-35195.patch @@ -0,0 +1,107 @@ +From 90fee0876aea97c639b3bf698d83a12876d2f160 Mon Sep 17 00:00:00 2001 +From: Nate Prewitt +Date: Fri, 13 Jun 2025 09:42:08 -0700 +Subject: [PATCH] Revert caching a default SSLContext (#6767) + +Reference:https://github.com/psf/requests/commit/90fee0876aea97c639b3bf698d83a12876d2f160 +Conflict:Adapt context +--- + requests/adapters.py | 55 +++++++++++++------------------------------- + 1 file changed, 16 insertions(+), 39 deletions(-) + +diff --git a/requests/adapters.py b/requests/adapters.py +index 29fe7ae..f54dd14 100644 +--- a/requests/adapters.py ++++ b/requests/adapters.py +@@ -16,7 +16,6 @@ from urllib3.response import HTTPResponse + from urllib3.util import parse_url + from urllib3.util import Timeout as TimeoutSauce + from urllib3.util.retry import Retry +-from urllib3.util.ssl_ import create_urllib3_context + from urllib3.exceptions import ClosedPoolError + from urllib3.exceptions import ConnectTimeoutError + from urllib3.exceptions import HTTPError as _HTTPError +@@ -53,19 +52,6 @@ DEFAULT_RETRIES = 0 + DEFAULT_POOL_TIMEOUT = None + + +-try: +- import ssl # noqa: F401 +- +- _preloaded_ssl_context = create_urllib3_context() +- _preloaded_ssl_context.load_verify_locations( +- extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) +- ) +-except ImportError: +- # Bypass default SSLContext creation when Python +- # interpreter isn't built with the ssl module. +- _preloaded_ssl_context = None +- +- + def _urllib3_request_context(request, verify, client_cert, poolmanager): + host_params = {} + pool_kwargs = {} +@@ -73,19 +59,9 @@ def _urllib3_request_context(request, verify, client_cert, poolmanager): + scheme = parsed_request_url.scheme.lower() + port = parsed_request_url.port + +- # Determine if we have and should use our default SSLContext +- # to optimize performance on standard requests. +- poolmanager_kwargs = getattr(poolmanager, "connection_pool_kw", {}) +- has_poolmanager_ssl_context = poolmanager_kwargs.get("ssl_context") +- should_use_default_ssl_context = ( +- _preloaded_ssl_context is not None and not has_poolmanager_ssl_context +- ) +- + cert_reqs = "CERT_REQUIRED" + if verify is False: + cert_reqs = "CERT_NONE" +- elif verify is True and should_use_default_ssl_context: +- pool_kwargs["ssl_context"] = _preloaded_ssl_context + elif isinstance(verify, str): + if not os.path.isdir(verify): + pool_kwargs["ca_certs"] = verify +@@ -270,26 +246,25 @@ class HTTPAdapter(BaseAdapter): + """ + if url.lower().startswith('https') and verify: + +- conn.cert_reqs = "CERT_REQUIRED" ++ cert_loc = None + +- # Only load the CA certificates if 'verify' is a string indicating the CA bundle to use. +- # Otherwise, if verify is a boolean, we don't load anything since +- # the connection will be using a context with the default certificates already loaded, +- # and this avoids a call to the slow load_verify_locations() ++ # Allow self-specified cert location. + if verify is not True: +- # `verify` must be a str with a path then + cert_loc = verify + +- if not os.path.exists(cert_loc): +- raise OSError( +- "Could not find a suitable TLS CA certificate bundle, " +- "invalid path: {}".format(cert_loc) +- ) ++ if not cert_loc: ++ cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) ++ ++ if not cert_loc or not os.path.exists(cert_loc): ++ raise IOError("Could not find a suitable TLS CA certificate bundle, " ++ "invalid path: {}".format(cert_loc)) + +- if not os.path.isdir(cert_loc): +- conn.ca_certs = cert_loc +- else: +- conn.ca_cert_dir = cert_loc ++ conn.cert_reqs = "CERT_REQUIRED" ++ ++ if not os.path.isdir(cert_loc): ++ conn.ca_certs = cert_loc ++ else: ++ conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None +-- +2.33.0 + diff --git a/python-requests.spec b/python-requests.spec index 972dfcf..e10f0ae 100644 --- a/python-requests.spec +++ b/python-requests.spec @@ -2,7 +2,7 @@ Name: python-requests Version: 2.24.0 -Release: 4 +Release: 5 Summary: Python HTTP Library License: ASL 2.0 URL: http://python-requests.org/ @@ -15,6 +15,14 @@ Patch4: Remove-tests-that-use-the-tarpit.patch Patch6000: backport-CVE-2023-32681.patch Patch6001: backport-CVE-2024-1682.patch Patch6002: backport-CVE-2024-47081.patch +Patch6003: backport-0001-CVE-2024-35195.patch +Patch6004: backport-0002-CVE-2024-35195.patch +Patch6005: backport-0003-CVE-2024-35195.patch +Patch6006: backport-0004-CVE-2024-35195.patch +Patch6007: backport-0005-CVE-2024-35195.patch +Patch6008: backport-0006-CVE-2024-35195.patch +Patch6009: backport-0007-CVE-2024-35195.patch +Patch6010: backport-0008-CVE-2024-35195.patch BuildArch: noarch @@ -115,6 +123,9 @@ PYTHONPATH=%{buildroot}%{python3_sitelib} %{__python3} -m pytest -v %doc HISTORY.md README.md %changelog +* Wed Nov 19 2025 lingsheng - 2.24.0-5 +- fix CVE-2024-35195 + * Mon Jun 23 2025 zhangpan - 2.24.0-4 - fix CVE-2024-47081 -- Gitee