<p dir="auto">Summary.</p>
<p dir="auto">When REQUESTS_CA_BUNDLE has been set as an environment variable, the verify property in a requests.Session() will always be ignored.</p>
<h2 dir="auto">Expected Result</h2>
<p dir="auto">requests.Session always uses REQUESTS_CA_BUNDLE unless a certificate bundle has been assigned</p>
<h2 dir="auto">Actual Result</h2>
<p dir="auto">requests.Session always uses REQUESTS_CA_BUNDLE and overides any certificate bundle set on the Session object.</p>
<h2 dir="auto">Reproduction Steps</h2>
<p dir="auto"><code class="notranslate">REQUESTS_CA_BUNDLE="/lib/python3.6/site-packages/pip/_vendor/certifi/cacert.pem"</code></p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import requests
s = requests.Session()
s.verify = &quot;/non_existing_bundle&quot;
s.get(&quot;https://google.com&quot;)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">requests</span>
<span class="pl-s1">s</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-v">Session</span>()
<span class="pl-s1">s</span>.<span class="pl-s1">verify</span> <span class="pl-c1">=</span> <span class="pl-s">"/non_existing_bundle"</span>
<span class="pl-s1">s</span>.<span class="pl-en">get</span>(<span class="pl-s">"https://google.com"</span>)</pre></div>
<p dir="auto">Expected result:<br>
<code class="notranslate">OSError: Could not find a suitable TLS CA certificate bundle, invalid path: /non_existing_bundle</code></p>
<p dir="auto">Actual result:<br>
<code class="notranslate">&lt;Response [200]&gt;</code></p>
<h2 dir="auto">System Information</h2>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ python -m requests.help"><pre class="notranslate"><code class="notranslate">$ python -m requests.help
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="{
  &quot;chardet&quot;: {
    &quot;version&quot;: &quot;3.0.4&quot;
  },
  &quot;cryptography&quot;: {
    &quot;version&quot;: &quot;&quot;
  },
  &quot;idna&quot;: {
    &quot;version&quot;: &quot;&quot;
  },
  &quot;implementation&quot;: {
    &quot;name&quot;: &quot;CPython&quot;,
    &quot;version&quot;: &quot;3.6.4&quot;
  },
  &quot;platform&quot;: {
    &quot;release&quot;: &quot;3.10.0-693.11.6.el7.x86_64&quot;,
    &quot;system&quot;: &quot;Linux&quot;
  },
  &quot;pyOpenSSL&quot;: {
    &quot;openssl_version&quot;: &quot;&quot;,
    &quot;version&quot;: null
  },
  &quot;requests&quot;: {
    &quot;version&quot;: &quot;2.18.4&quot;
  },
  &quot;system_ssl&quot;: {
    &quot;version&quot;: &quot;100020bf&quot;
  },
  &quot;urllib3&quot;: {
    &quot;version&quot;: &quot;1.22&quot;
  },
  &quot;using_pyopenssl&quot;: false
}"><pre class="notranslate"><code class="notranslate">{
  "chardet": {
    "version": "3.0.4"
  },
  "cryptography": {
    "version": ""
  },
  "idna": {
    "version": ""
  },
  "implementation": {
    "name": "CPython",
    "version": "3.6.4"
  },
  "platform": {
    "release": "3.10.0-693.11.6.el7.x86_64",
    "system": "Linux"
  },
  "pyOpenSSL": {
    "openssl_version": "",
    "version": null
  },
  "requests": {
    "version": "2.18.4"
  },
  "system_ssl": {
    "version": "100020bf"
  },
  "urllib3": {
    "version": "1.22"
  },
  "using_pyopenssl": false
}
</code></pre></div>
<p dir="auto">Not sure if this is a bug, but I now need to unset the environment variable first before I can use a different certificate bundle in a session object or use the following workaround.</p>
<p dir="auto">sessions.py:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="            #if verify is True or verify is None:
            if verify is True or verify is None and not isinstance(self.verify, str):
                verify = (os.environ.get('REQUESTS_CA_BUNDLE') or
                          os.environ.get('CURL_CA_BUNDLE'))"><pre class="notranslate"><code class="notranslate">            #if verify is True or verify is None:
            if verify is True or verify is None and not isinstance(self.verify, str):
                verify = (os.environ.get('REQUESTS_CA_BUNDLE') or
                          os.environ.get('CURL_CA_BUNDLE'))
</code></pre></div>
<p dir="auto">One would expect that when the caller explicitly asks to make unverified requests, then the <code class="notranslate">REQUESTS_CA_BUNDLE</code> environment variable doesn't affect it. The reality is different, however.</p>
<div class="highlight highlight-source-python notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="import os
import requests

os.environ['REQUESTS_CA_BUNDLE'] = 'asd.pem'  # Must be an existing file

r = requests.get('https://self-signed.badssl.com/', verify=False)
print(r)
# Prints: &lt;Response [200]&gt;

session = requests.Session()
session.verify = False

r = session.get('https://self-signed.badssl.com/')
print(r)
# Fails: requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)"><pre class="notranslate"><span class="pl-k">import</span> <span class="pl-s1">os</span>
<span class="pl-k">import</span> <span class="pl-s1">requests</span>

<span class="pl-s1">os</span>.<span class="pl-s1">environ</span>[<span class="pl-s">'REQUESTS_CA_BUNDLE'</span>] <span class="pl-c1">=</span> <span class="pl-s">'asd.pem'</span>  <span class="pl-c"># Must be an existing file</span>

<span class="pl-s1">r</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-en">get</span>(<span class="pl-s">'https://self-signed.badssl.com/'</span>, <span class="pl-s1">verify</span><span class="pl-c1">=</span><span class="pl-c1">False</span>)
<span class="pl-en">print</span>(<span class="pl-s1">r</span>)
<span class="pl-c"># Prints: &lt;Response [200]&gt;</span>

<span class="pl-s1">session</span> <span class="pl-c1">=</span> <span class="pl-s1">requests</span>.<span class="pl-v">Session</span>()
<span class="pl-s1">session</span>.<span class="pl-s1">verify</span> <span class="pl-c1">=</span> <span class="pl-c1">False</span>

<span class="pl-s1">r</span> <span class="pl-c1">=</span> <span class="pl-s1">session</span>.<span class="pl-en">get</span>(<span class="pl-s">'https://self-signed.badssl.com/'</span>)
<span class="pl-en">print</span>(<span class="pl-s1">r</span>)
<span class="pl-c"># Fails: requests.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)</span></pre></div>