Ignorieren Sie die Prüfung des SSL-Sicherheitszertifikats in Python-Anforderungen
- Den Grund hinter SSL-Sicherheitsprüfungen verstehen und warum sie fehlschlagen
- Ignorieren Sie die SSL-Sicherheitsprüfung in Python
- Abschluss
Der Zugriff auf eine URL ohne ein sicheres SSL-Zertifikat löst Ausnahmewarnungen aus, wenn HTTP-Anforderungen an sie gesendet werden. Oft läuft das SSL-Zertifikat dieser URLs ab, wodurch alle möglichen Sicherheitsprobleme entstehen.
Wenn die Informationen nicht sensibel sind, können diese Warnungen unterbunden werden, wenn Programme requests
in Python verwenden. In diesem Artikel werden mehrere Möglichkeiten zum Deaktivieren von Sicherheitszertifikatprüfungen mithilfe von Anforderungen
vorgestellt.
Den Grund hinter SSL-Sicherheitsprüfungen verstehen und warum sie fehlschlagen
Wenn ein Programm Python-Anfragen verwendet, um Anfragen von einer URL zu erhalten, deren SSL-Zertifikat abgelaufen ist, löst es zwei Ausnahmen aus. Das folgende Programm zeigt, was diese Ausnahmen sind.
Szenario 1
Dieses Programm verwendet zu Testzwecken eine von der SSL-Community bereitgestellte URL mit einem abgelaufenen Sicherheitszertifikat. Es ist zu beachten, dass die SSL
-Sicherheitsausnahmen nur bei URLs mit abgelaufenen SSL
-Zertifikaten auftreten.
Die Python-requests
lösen keine Ausnahme bei URLs mit gültigem oder widerrufenem SSL
-Zertifikat aus. Daher konzentriert sich dieser Artikel hauptsächlich auf URLs mit abgelaufenen Sicherheitszertifikaten.
Das folgende Beispiel zeigt ein einfaches Programm, das in der ersten Zeile Anfragen
importiert. Die zweite Zeile des Programms sendet eine post
-Anforderung an die URL, um Vorkommen von 'bar'
in 'baz'
zu ändern.
Es wird getan, um eine post
-Anfrage an die URL zu senden, und hat innerhalb des Programms keine andere Bedeutung.
import requests
requests.post(url="https://expired-rsa-dv.ssl.com/", data={"bar": "baz"})
Die Ausführung dieses Python-Skripts löst SSLError
-Ausnahmen aus.
....
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='expired-rsa-dv.ssl.com', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:841)'),))
Dies ist die erste Ausnahme, die berücksichtigt werden muss, um zu lernen, wie man Sicherheitszertifikatsprüfungen mit requests
deaktiviert.
Szenario 2
Dieses Programm schaltet die Prüfung des SSL
-Zertifikats mit verify=False
ab, um die Prüfung des Sicherheitszertifikats mit requests
zu deaktivieren.
import requests
requests.post(url="https://expired-rsa-dv.ssl.com/", data={"bar": "baz"}, verify=False)
Die requests
-Bibliothek ist so aufgebaut, dass sie die Überprüfung für SSL
-Zertifikate deaktivieren kann, aber das Programm wirft eine weitere Ausnahme mit Links mit abgelaufenen SSL
-Zertifikaten.
InsecureRequestWarning: Unverified HTTPS request is being made to host 'expired-rsa-dv.ssl.com'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/1.26.x/advanced-usage.html#ssl-warnings
InsecureRequestWarning,
Diese beiden Ausnahmen müssen behandelt werden, um die Überprüfung von Sicherheitszertifikaten mit Anforderungen
zu deaktivieren.
Ignorieren Sie die SSL-Sicherheitsprüfung in Python
In diesem Abschnitt werden verschiedene Methoden erläutert, die entweder die Überprüfung von Sicherheitszertifikaten mithilfe von Anforderungen
deaktivieren oder das Problem umkehren. Jede Methode hat ihren Zweck.
Erstellen Sie einen Monkey Patch für die Bibliothek requests
Wenn eine Bibliothek eines Drittanbieters die Deaktivierung der Sicherheitsüberprüfungen erfordert, kann die Bibliothek Anforderungen
monkey patched werden. Beim Patchen wird ein Kontextmanager verwendet, um Sicherheitszertifikatsprüfungen mittels requests
zu deaktivieren.
Nach dem Patchen der requests
erhält das verify
-Feld standardmäßig einen False
-Wert, wodurch die Warnung unterdrückt wird. Eine weitere Warnung wird ausgegeben, wenn verify=false
verwendet wird, wie in Szenario 2 des vorherigen Abschnitts erläutert.
Der Patch fügt dann einen Ausnahmebehandlungsblock hinzu, um die Prüfung von Sicherheitszertifikaten mit Anforderungen
zu deaktivieren, und unterdrückt die Warnungen. Mit den folgenden Beispielen wird es einfacher zu verstehen.
Das folgende Programm patcht die Bibliothek requests
. Lassen Sie uns verstehen, was dieser Code tut.
Importe:
warnings
: Dieses Bibliothekspaket ist ein Unterpaket derExceptions
-Bibliothek.contextlib
: Diese Python-Bibliothek wird zum Patchen der Bibliothekrequests
verwendet.requests
: Das Requests-Bibliothekspaket von Python.urllib3
: Es ist ein Modul, das HTTP-Anfragen und URLs in Python verarbeitet. Diese Bibliothek wird verwendet, um ein UntermodulInsecureRequestWarning
zu importieren, das eine Ausnahme für abgelaufeneSSL
-Zertifikate auslöst.
Aufnäher:
Zunächst speichert das Programm die Standardumgebungseinstellungen der Bibliothek requests
in einer Variablen - old_merge_environment_settings
. Diese Variable wird verwendet, um Anforderungen
wieder in ihren Standardzustand zu bringen, nachdem die geöffneten Adapter geschlossen wurden.
old_merge_environment_settings = requests.Session.merge_environment_settings
Die Methode no_ssl_verification
wird erstellt und mit @contextlib.contextmanager
dekoriert. Eine neue Variable opened_adapters
wird erstellt und ihr ein set()
zugewiesen.
Ein Set ist ein Datentyp, der Elemente in einem ungeordneten Format speichert.
@contextlib.contextmanager
def no_ssl_verification():
opened_adapters = set()
Innerhalb der Methode no_ssl_verification
wird eine weitere verschachtelte Methode merge_environment_settings
erstellt. Diese Methode hat sechs Parameter, ähnlich den merge_environment_settings
aus dem requests
-Modul, und fungiert als Patch für das ursprüngliche Modul.
def merge_environment_settings(self, url, proxies, stream, verify, cert):
Innerhalb der Methode wird die Variable opened_adapters
mit dem passenden Adapterpaar aus dem Parameter url
aktualisiert. Jede Verbindung wird mit einem passenden Adapterpaar hergestellt, das in diesem Schritt zurückgegeben wird.
Da die Überprüfung nur einmal pro Verbindung erfolgt, müssen wir alle geöffneten Adapter schließen, nachdem wir fertig sind. Wenn nicht, bleiben die Wirkungen von verify=False
bestehen, nachdem dieser Kontextmanager beendet wurde.
def merge_environment_settings(self, url, proxies, stream, verify, cert):
opened_adapters.add(self.get_adapter(url))
Es ist wichtig, sich an den ersten Abschnitt des Artikels zu erinnern, um die nächste Codezeile zu verstehen. Wenn die Funktion requests.post
auf der URL mit einem abgelaufenen SSL
-Zertifikat verwendet wurde, wurden zwei Ausnahmen ausgelöst.
Die erste Ausnahme wurde durch verify
verursacht, das mit einem True
-Wert gesetzt ist. Das verify
-Feld war zwar schaltbar, konnte aber mit einem False
-Wert belegt werden.
Die zweite Ausnahme war eine nicht änderbare Entität, die das Programm daran hinderte, eine Verbindung herzustellen.
Der folgende Code ändert das Feld verify
so, dass es standardmäßig einen False
-Wert hat, um dieses Problem zu lösen. Zur Ausführung dieses Schrittes wird eine neue Variable settings
erstellt, die mit Daten aus der Variablen old_merge_environment_settings
belegt wird.
Sobald die Daten in der Variablen settings
gespeichert sind, wird das Feld verify
auf False
gesetzt.
Dadurch ändert sich der Standardwert von verify
. Zuletzt wird diese Variable zurückgegeben.
settings = old_merge_environment_settings(self, url, proxies, stream, verify, cert)
settings["verify"] = False
return settings
Die Daten der aktualisierten Methode merge_environment_settings
werden der Funktion requests.Session.merge_environment_settings
zugewiesen. Dadurch wird sichergestellt, dass das Feld verify
standardmäßig einen False
-Wert hat.
requests.Session.merge_environment_settings = merge_environment_settings
Die erste Ausnahme haben wir behandelt. Die zweite Ausnahme, die nicht änderbar ist, wird mithilfe eines Ausnahmebehandlungsblocks gelöst.
Lassen Sie uns verstehen, was der Code hier tut.
Zuerst wird innerhalb des try
-Blocks ein with
-Block erstellt, der alle ausgegebenen Warnungen abfängt. Innerhalb dieses with
-Blocks wird die warnings.simplefilter
-Funktion verwendet, um dem urllib3
-Untermodul InsecureRequestWarning
einen ignore
-Wert zuzuweisen.
Wie wir im Importabschnitt erfahren haben, löst das Untermodul InsecureRequestWarning
eine Ausnahme für ablaufende SSL
-Zertifikate aus; die Zuweisung eines Ignorieren
-Werts umgeht die zweite verursachte Ausnahme.
try:
with warnings.catch_warnings():
warnings.simplefilter('ignore', InsecureRequestWarning)
yield
Innerhalb des Blocks finally
werden die ursprünglichen Einstellungen, die in old_merge_environment_settings
gespeichert sind, der Funktion requests.Session.merge_environment_settings
wieder zugewiesen.
Da alle geöffneten Adapter geschlossen werden müssen, bevor das Programm beendet wird, wird eine for
-Schleife erstellt, die so oft wiederholt wird, wie oft geöffnete Adapter im Programm vorhanden sind.
Alle Adapter werden mit der Funktion adapter.close()
mit einem try-except
-Block geschlossen; innerhalb des außer
-Blocks wird die Iteration übergeben.
for adapter in opened_adapters:
try:
adapter.close()
except:
pass
Der vollständige Code ist unten angegeben.
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):
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
Verwenden Sie Monkey Patch in Python
Der Monkey-Patch kann mit der Methode no_ssl_verification()
aufgerufen werden. Jede Anfrage, die mit dieser Methode gesendet wird, folgt den Anweisungen des Affen-Patches und deaktiviert die Überprüfung von Sicherheitszertifikaten mit Anfragen
.
Schauen wir uns ein Beispiel an.
Die Methode no_ssl_verification
wird unter einem with
-Block aufgerufen. Dies führt die Methode innerhalb des Blocks aus und schließt sich dann selbst, wenn der Compiler aus dem Block kommt.
Innerhalb des Blocks wird ein requests.get
-Aufruf an die URL mit einem abgelaufenen SSL
-Zertifikat gesendet. Mit den Standardeinstellungen hätte dies einen Ausnahmewurf verursacht, aber diesmal wird der requests.get
-Aufruf erfolgreich gesendet.
Eine weitere Anfrage wird mit den requests
gesendet, wobei das verify
-Feld auf True
gesetzt ist. Im Gegensatz zum Standardszenario wird diesmal keine Fehlerausnahme ausgelöst.
with no_ssl_verification():
requests.get("https://expired-rsa-dv.ssl.com/")
print("Modifications working Properly")
requests.get("https://expired-rsa-dv.ssl.com/", verify=True)
print("`Verify=true` has its meaning changed")
Ausgang:
Modifications working Properly
`Verify=true` has its meaning changed
Es wurde gesehen, dass Verify=False
die Anweisungen hatte, den Patch mit den Standardeinstellungen zurückzusetzen. Wenn dieses Feld in requests.get()
gesetzt wurde, wird der Monkey-Patch auf die Standardeinstellungen zurückgesetzt, wodurch Fehlerausnahmen ausgelöst werden können.
requests.get("https://expired-rsa-dv.ssl.com/", verify=False)
print("It resets back")
Ausgang:
connectionpool.py:1052: InsecureRequestWarning: Unverified HTTPS request is being made to host 'expired-rsa-dv.ssl.com'.
InsecureRequestWarning,
It resets back
Das requests
-Untermodul session
kann auch mit dem Monkey-Patch verwendet werden.
In eine Variable namens session
wird die Funktion requests.Session()
geladen. Der Wert session.verify
wird auf True
gesetzt.
Innerhalb eines with
-Blocks wird die session.get()
-Funktion verwendet, um die get
-Anforderung an die URL zu senden, und das verify
-Feld wird auf True
gesetzt. Eine print
-Anweisung gibt eine Nachricht aus, wenn die Verbindung hergestellt wurde.
session = requests.Session()
session.verify = True
with no_ssl_verification():
session.get("https://expired-rsa-dv.ssl.com/", verify=True)
print("Works in Session")
Ausgang:
Works in Session
Wenn der Kontextmanager beendet wird, schließt dieser Code alle offenen Adapter, die eine gepatchte Anforderung verarbeiten. Da requests
für jede Sitzung einen Verbindungspool verwaltet und die Zertifikatsvalidierung nur einmal pro Verbindung erfolgt, treten unerwartete Ereignisse wie die folgenden auf.
try:
requests.get("https://expired-rsa-dv.ssl.com/", verify=False)
except requests.exceptions.SSLError:
print("It breaks")
try:
session.get("https://expired-rsa-dv.ssl.com/")
except requests.exceptions.SSLError:
print("It breaks here again")
Ausgang:
C:\Users\Win 10\venv\lib\site-packages\urllib3\connectionpool.py:1052: InsecureRequestWarning: Unverified HTTPS request is being made to host 'expired-rsa-dv.ssl.com'.
InsecureRequestWarning,
It breaks here again
Verwenden Sie urllib3
, um Warnungen in Python zu deaktivieren
Wenn das Programm die Deaktivierung von Sicherheitszertifikatsprüfungen erfordert, ohne requests
oder Monkey-Patching zu verwenden, bietet die Verwendung von urllib3
eine einfache Lösung.
Importieren Sie requests
und urllib3
und importieren Sie aus urllib3
das Submodul InsecureRequestWarning
. Die Warnung wird mit der Funktion urllib3.disable_warnings
deaktiviert.
Die Anweisung requests.post()
wird unter den Block try
gestellt und das Feld verify
auf False
gesetzt. Dadurch wird die Sicherheitsprüfung für abgelaufene Sicherheitszertifikate deaktiviert.
Innerhalb des except
-Blocks wird SSLError
mit einer Fehlermeldung ausgelöst.
import requests
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
try:
requests.post(
url="https://expired-rsa-dv.ssl.com/", data={"bar": "baz"}, verify=False
)
print("Connection made successfully")
except requests.exceptions.SSLError:
print("Expired Certificate")
Ausgang:
Connection made successfully
Abschluss
Dieser Artikel erklärt verschiedene Methoden zum Deaktivieren von Sicherheitszertifikatsprüfungen mit Anfragen
in Python. Der Leser kann durch den Artikel Sicherheitsüberprüfungen einfach deaktivieren.