I'm running a Python script that uses the requests
package for making web requests. However, the web requests go through a proxy with a self-signed cert. As such, requests raise the following Exception:
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)",)
I know that SSL validation can be disabled in my own code by passing verify=False
, e.g.: requests.get("https://www.google.com", verify=False)
. I also know that if I had the certificate bundle, I could set the REQUESTS_CA_BUNDLE
or CURL_CA_BUNDLE
environment variables to point to those files. However, I do not have the certificate bundle available.
How can I disable SSL validation for external modules without editing their code?
Note: This solution is a complete hack.
Short answer: Set the
CURL_CA_BUNDLE
environment variable to an empty string.Before:
After:
How it works
This solution works because Python
requests
overwrites the default value forverify
from the environment variablesCURL_CA_BUNDLE
andREQUESTS_CA_BUNDLE
, as can be seen here:The environment variables are meant to specify the path to the certificate file or CA_BUNDLE and are copied into
verify
. However, by settingCURL_CA_BUNDLE
to an empty string, the empty string is copied intoverify
and in Python, an empty string evaluates toFalse
.Note that this hack only works with the
CURL_CA_BUNDLE
environment variable - it does not work with theREQUESTS_CA_BUNDLE
. This is becauseverify
is set with the following statement:verify = (os.environ.get('REQUESTS_CA_BUNDLE') or os.environ.get('CURL_CA_BUNDLE'))
It only works with
CURL_CA_BUNDLE
because'' or None
is not the same asNone or ''
, as can be seen below: