Wie deaktiviere ich die Sicherheitszertifikatsprüfung in Python-Anforderungen?

230

ich benutze

import requests
requests.post(url='https://foo.com', data={'bar':'baz'})

aber ich bekomme eine request.exceptions.SSLError. Die Website hat ein abgelaufenes Zertifikat, aber ich sende keine sensiblen Daten, daher ist es mir egal. Ich würde mir vorstellen, dass es ein Argument wie 'verifiy = False' gibt, das ich verwenden könnte, aber ich kann es scheinbar nicht finden.

Paul Draper
quelle

Antworten:

411

Aus der Dokumentation :

requestsSie können die Überprüfung des SSL-Zertifikats auch ignorieren, wenn Sie verifyFalse festlegen .

>>> requests.get('https://kennethreitz.com', verify=False)
<Response [200]>

Wenn Sie ein Modul eines Drittanbieters verwenden und die Überprüfungen deaktivieren möchten, finden Sie hier einen Kontextmanager, der Affen-Patches erstellt requestsund so ändert, dass dies verify=Falsedie Standardeinstellung ist und die Warnung unterdrückt.

import warnings
import contextlib

import requests
from urllib3.exceptions import InsecureRequestWarning


old_merge_environment_settings = requests.Session.merge_environment_settings

@contextlib.contextmanager
def no_ssl_verification():
    opened_adapters = set()

    def merge_environment_settings(self, url, proxies, stream, verify, cert):
        # Verification happens only once per connection so we need to close
        # all the opened adapters once we're done. Otherwise, the effects of
        # verify=False persist beyond the end of this context manager.
        opened_adapters.add(self.get_adapter(url))

        settings = old_merge_environment_settings(self, url, proxies, stream, verify, cert)
        settings['verify'] = False

        return settings

    requests.Session.merge_environment_settings = merge_environment_settings

    try:
        with warnings.catch_warnings():
            warnings.simplefilter('ignore', InsecureRequestWarning)
            yield
    finally:
        requests.Session.merge_environment_settings = old_merge_environment_settings

        for adapter in opened_adapters:
            try:
                adapter.close()
            except:
                pass

So verwenden Sie es:

with no_ssl_verification():
    requests.get('https://wrong.host.badssl.com/')
    print('It works')

    requests.get('https://wrong.host.badssl.com/', verify=True)
    print('Even if you try to force it to')

requests.get('https://wrong.host.badssl.com/', verify=False)
print('It resets back')

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

with no_ssl_verification():
    session.get('https://wrong.host.badssl.com/', verify=True)
    print('Works even here')

try:
    requests.get('https://wrong.host.badssl.com/')
except requests.exceptions.SSLError:
    print('It breaks')

try:
    session.get('https://wrong.host.badssl.com/')
except requests.exceptions.SSLError:
    print('It breaks here again')

Beachten Sie, dass dieser Code alle offenen Adapter schließt, die eine gepatchte Anforderung verarbeitet haben, sobald Sie den Kontextmanager verlassen. Dies liegt daran, dass Anforderungen einen Verbindungspool pro Sitzung verwalten und die Zertifikatsüberprüfung nur einmal pro Verbindung erfolgt, sodass unerwartete Ereignisse wie diese auftreten:

>>> import requests
>>> session = requests.Session()
>>> session.get('https://wrong.host.badssl.com/', verify=False)
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:857: 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]>
>>> session.get('https://wrong.host.badssl.com/', verify=True)
/usr/local/lib/python3.7/site-packages/urllib3/connectionpool.py:857: 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]>
Mixer
quelle
6
Vielen Dank, dies funktioniert, wenn Sie nur wenige Anfragen in Ihrem eigenen Code haben, aber stellen Sie sich vor, ich möchte dies in einer dritten teilweise Bibliothek deaktivieren, die Anfragen verwendet. Es wäre unmöglich, die Bibliothek eines Drittanbieters so zu reparieren.
Sorin
7
@sorin: Nur Affen Patch requestsund haben verifystandardmäßig zu False.
Blender
2
Wie unterdrücke ich die große böse Warnmeldung, die noch gedruckt wird?
Michael
27
@ requests.packages.urllib3.disable_warnings()
Michael
8
@ Michael: oder um nicht alle Warnungen zu verbergen: from urllib3.exceptions import InsecureRequestWarningdannrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez
96

Verwenden Sie requests.packages.urllib3.disable_warnings()und verify=Falseauf requestsMethoden.

import requests
from urllib3.exceptions import InsecureRequestWarning

# Suppress only the single warning from urllib3 needed.
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

# Set `verify=False` on `requests.post`.
requests.post(url='https://example.com', data={'bar':'baz'}, verify=False)
efrenfuentes
quelle
11
Ihre Antwort ist nützlich, wenn Sie Warnungen wie "Nicht überprüfte HTTPS-Anforderung wird erstellt" entfernen möchten. Aber verify=Falsemuss ohnehin vorhanden sein. Tnx.
Lufa
17
Und um nicht alle Warnungen zu verbergen: from urllib3.exceptions import InsecureRequestWarningdannrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez
Für diejenigen, die Warnungen nicht deaktivieren können, können Sie versuchen requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Dies funktioniert, weil es sicherstellt, dass es urllib3.exceptions.InsecureRequestWarninggenau das ist, das von verwendet wird requests.
AnnieFromTaiwan
32

Um die Antwort von Blender zu ergänzen , können Sie SSL für alle Anforderungen mit deaktivierenSession.verify = False

import requests

session = requests.Session()
session.verify = False
session.post(url='https://foo.com', data={'bar':'baz'})

Beachten Sie, dass urllib3(von Requests verwendet) nicht bestätigte HTTPS-Anfragen dringend empfohlen werden und eine InsecureRequestWarning.

Stevoisiak
quelle
11

Kann auch über die Umgebungsvariable erfolgen:

export CURL_CA_BUNDLE=""
Stan Gabenov
quelle
1
Das gibt mir: „OSError: Es kann kein geeignetes TLS - CA - Zertifikat Bündel, ungültigen Pfad:‚‘Ich verwende Anfrage 2.22.0.
Chaim
oderexport REQUESTS_CA_BUNDLE='your-ca.pem'
Weaming
1
Dies scheint die beste Antwort zu sein, falls Sie eine Bibliothek verwenden müssen, die Sie nicht bearbeiten können
user989762
Basierend auf CURL_CA_BUNDLE , os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemfunktioniert für Python 3.8.3, wenn Google-Cloud-Bigquery 1.24.0 und BigQuery Client Lib für Python verwendet werden
Samm
8

Wenn Sie genau eine Post-Anfrage mit der Option verify = False senden möchten, verwenden Sie am schnellsten diesen Code:

import requests

requests.api.request('post', url, data={'bar':'baz'}, json=None, verify=False)
Ruslan Khyurri
quelle
Bandit wird nicht glücklich sein, wenn Sie verify = False deaktivieren. Siehe: docs.openstack.org/bandit/latest/plugins/…
kRazzy R
Hallo, ich habe eine Anfrage, die mir die Antwort auf eine Post-Anfrage im Postman gibt, indem ich die 'SSL-Zertifikatsüberprüfung' in der Einstellungsoption deaktiviere. Wenn ich jedoch den vom Postboten bereitgestellten Python-Anforderungscode erhalte, erhalte ich den Fehler "SSL-Routinen", "tls_process_server_certificate", "Zertifikatüberprüfung fehlgeschlagen" und das Hinzufügen von "verify = False" hilft in diesem Fall nicht Gibt es eine Lösung, um die Antwort des Postboten im Python-Anforderungsskript zu erhalten?
Taha Hamedani