python requests: How to ignore invalid SSL certificates

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.

Jump to Solution

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
certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings

…\venv\lib\site-packages\urllib3\connectionpool.py:986

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)

References

3 Replies to “python requests: How to ignore invalid SSL certificates”

  1. 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’])
    “`

  2. 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.

  3. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.