Skip to content

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

@sunnstix

Description

@sunnstix

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
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions