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

Wrong CA Certificates used in requests.Session.send #6647

Open
sunnstix opened this issue Feb 23, 2024 · 1 comment
Open

Wrong CA Certificates used in requests.Session.send #6647

sunnstix opened this issue Feb 23, 2024 · 1 comment

Comments

@sunnstix
Copy link

sunnstix commented Feb 23, 2024

Bug in requests.sessions.py:

settings = self.merge_environment_settings(
prep.url, proxies, stream, verify, cert
)
# Send the request.
send_kwargs = {
"timeout": timeout,
"allow_redirects": allow_redirects,
}
send_kwargs.update(settings)
resp = self.send(prep, **send_kwargs)

session.merge_environment_settings is called in session.request and not in session.send which means if users want to build their own prepared requests (see example below), the correct certificates file will not be used unless explicitly passed to send.

I believe these environment settings should be updated in session.send instead.

Reproduction Steps

import os
import requests

# Set CA certificates file to custom local file
os.environ["REQUESTS_CA_BUNDLE"] = "/etc/ssl/certs/ca-certificates.crt"

# Create request object
req = requests.Request(
    method="GET", # any method
    url="https://www.example_site.mydomain.com/path" # any url for which the default cert file does not have a cert for
)

with requests.Session() as s:
    respA = s.request( # Success: will use CA certificates from REQUESTS_CA_BUNDLE
        method=req.method,
        url=req.url
    )
    assert respA.status_code == 200
    
with requests.Session() as s:
    respB = s.send( # Success: will use CA certificates from REQUESTS_CA_BUNDLE if explicitly specified
        request=req.prepare(), verify=os.environ["REQUESTS_CA_BUNDLE"]
    )
    
    assert respB.status_code == 200
    
with requests.Session() as s:
    respC = s.send( # Error: Will try to use default CA certificates instead of those specified by REQUESTS_CA_BUNDLE
        request=req.prepare() 
    )
    
    assert respC.status_code == 200

Expected Result

No output

Actual Result

requests.exceptions.SSLError: HTTPSConnectionPool(host='https://www.example_site.mydomain.com/path', port=443): Max retries exceeded with url: /path (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:997)')))

System Information

$ python -m requests.help
{
  "chardet": {
    "version": null
  },
  "charset_normalizer": {
    "version": "3.3.2"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": "3.6"
  },
  "implementation": {
    "name": "CPython",
    "version": "3.10.4"
  },
  "platform": {
    "release": "5.4.0-150-generic",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.31.0"
  },
  "system_ssl": {
    "version": "30000020"
  },
  "urllib3": {
    "version": "2.2.1"
  },
  "using_charset_normalizer": true,
  "using_pyopenssl": false
}
@sunnstix sunnstix changed the title Wrong CA Certificates file used in requests.Session.send Wrong CA Certificates used in requests.Session.send Feb 23, 2024
@bmeneg
Copy link

bmeneg commented May 30, 2024

I can confirm I'm seeing this behavior when using prepared requests and sessions.send(), being forced to set session.verify = os.environ['REQUESTS_CA_BUNDLE'] before send().

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants