python requests: How to ignore invalid SSL certificates
How to make an SSL web request with the python requests library and ignore invalid SSL certificates. Typically you would want the remote host to have a valid SSL certificate when making an https request but there are also some valid use cases where you need to ignore server SSL certs. One good example is when communicating with network devices such as local network equipment such as routers, access-points, wireless bridge radios, and IoT devices.
Here is the error and traceback you received when your python code attempts to make an https request to a host that have an invalid or expired SSL certificate.
Error
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)
Traceback
During handling of the above exception, another exception occurred: Traceback (most recent call last): File "...\filepath\script.py", line 23, in response = requests.request("POST", base_url + uris['login'], headers=headers, data = payload ) File "...\venv\lib\site-packages\requests\api.py", line 61, in request return session.request(method=method, url=url, **kwargs) File "...\venv\lib\site-packages\requests\sessions.py", line 530, in request resp = self.send(prep, **send_kwargs) File "...\venv\lib\site-packages\requests\sessions.py", line 643, in send r = adapter.send(request, **kwargs) File "...\venv\lib\site-packages\requests\adapters.py", line 514, in send raise SSLError(e, request=request) requests.exceptions.SSLError: HTTPSConnectionPool(host='192.168.1.1', port=443): \ Max retries exceeded with url: /login.cgi (Caused by SSLError(SSLCertVerificationError( \ 1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)' )))
Solution
You need to Add verify=False
to the call to requests.get()
or request.post()
. Here is an example
// GET Request
response = requests.get(
"https://192.168.1.1/",
headers=headers,
verify=False # <---- Added
)
// POST Request
response = requests.request(
"POST",
"https://192.168.1.1/login.cgi",
headers=headers,
data = payload,
verify=False # <---- Added
)
Catching the Exception
Here is an example when you expect a valid SSL and want to gracefully catch the exception without halting executing.
# TODO add try catch example
try:
response = session.get(url,allow_redirects=False,verify=True)
except requests.exceptions.SSLError:
pass
Suppress InsecureRequestWarning
After adding verify=False you may notice that you will now get warnings from urllib3 output to the console when running your script.
InsecureRequestWarning: Unverified HTTPS request is being made to host ‘192.168.1.1’. Adding
…\venv\lib\site-packages\urllib3\connectionpool.py:986
certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
You can suppress these warning by adding the following code snippet. This code should execute before any https calls.
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
3 Replies to “python requests: How to ignore invalid SSL certificates”
That’s a very bad solution indeed.
Adding the certificate to the trust store or using a new one is the solution to go. The warnings are there for a reason.
One of several ways to do this is to use environment variables:
“`
SSL_CERT_FILE=cert.pem
REQUESTS_CA_BUNDLE=cert.pem
“`
Or
“`
requests.get(‘https://example.com’, verify=True, cert=[‘/path/ca.crt’])
“`
Actually, this is very useful. My app had to talk to a server that has an invalid SSL certificated and there was nothing I could do to fix it. I had to add “verify=false” to the code and after that only warnings remained. These can be turned off as explained if necessary but I liked them to stay.
I agree, this is very helpful. For instance, if a performing ZTP (Zero Touch Provisioning) on a device, the initial connections may require an insecure connection in order to provision certificates and configuration. Thank you.