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,
Note: This solution is a complete hack.
Short answer: Set the CURL_CA_BUNDLE
environment variable to an empty string.
Before:
$ python
import requests
requests.get('http://www.google.com')
<Response [200]>
requests.get('https://www.google.com')
...
File "/usr/local/lib/python2.7/site-packages/requests-2.17.3-py2.7.egg/requests/adapters.py", line 514, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: ("bad handshake: Error([('SSL routines', 'SSL3_GET_SERVER_CERTIFICATE', 'certificate verify failed')],)",)
After:
$ CURL_CA_BUNDLE="" python
import requests
requests.get('http://www.google.com')
<Response [200]>
requests.get('https://www.google.com')
/usr/local/lib/python2.7/site-packages/urllib3-1.21.1-py2.7.egg/urllib3/connectionpool.py:852: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning)
<Response [200]>
How it works
This solution works because Python requests
overwrites the default value for verify
from the environment variables CURL_CA_BUNDLE
and REQUESTS_CA_BUNDLE
, as can be seen here:
if verify is True or verify is None:
verify = (os.environ.get('REQUESTS_CA_BUNDLE') or
os.environ.get('CURL_CA_BUNDLE'))
The environment variables are meant to specify the path to the certificate file or CA_BUNDLE and are copied into verify
. However, by setting CURL_CA_BUNDLE
to an empty string, the empty string is copied into verify
and in Python, an empty string evaluates to False
.
Note that this hack only works with the CURL_CA_BUNDLE
environment variable - it does not work with the REQUESTS_CA_BUNDLE
. This is because verify
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 as None or ''
, as can be seen below:
print repr(None or "")
# Prints: ''
print repr("" or None )
# Prints: None