Comment désactiver la vérification du certificat de sécurité dans les demandes Python


230

j'utilise

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

mais j'obtiens une request.exceptions.SSLError. Le site Web a un certificat expiré, mais je n'envoie pas de données sensibles, donc cela ne m'importe pas. J'imagine qu'il y a un argument comme «verifiy = False» que je pourrais utiliser, mais je n'arrive pas à le trouver.

Réponses:


411

De la documentation :

requestspeut également ignorer la vérification du certificat SSL si vous définissez verifysur False.

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

Si vous utilisez un module tiers et que vous souhaitez désactiver les vérifications, voici un gestionnaire de contexte qui corrige le singe requestset le modifie de manière à ce qu'il verify=Falsesoit par défaut et supprime l'avertissement.

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

Voici comment vous l'utilisez:

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')

Notez que ce code ferme tous les adaptateurs ouverts qui ont traité une demande corrigée une fois que vous quittez le gestionnaire de contexte. En effet, les demandes conservent un pool de connexions par session et la validation de certificat ne se produit qu'une seule fois par connexion, des événements inattendus comme celui-ci se produiront:

>>> 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]>

6
Merci, cela fonctionne si vous avez peu d'appels de requêtes dans votre propre code, mais imaginez que je veux désactiver cela dans une troisième bibliothèque en partie qui utilise des requêtes, ... il serait impossible de réparer la bibliothèque tierce comme ceci.
sorin

7
@sorin: Juste un patch de singe requestset verifypar défaut False.
Blender

2
Comment supprimer le gros message d'avertissement désagréable qui reste imprimé?
Michael

27
@Michael pour répondre à ma propre question:requests.packages.urllib3.disable_warnings()
Michael

8
@Michael: ou pour éviter de cacher tous les avertissements: from urllib3.exceptions import InsecureRequestWarningalorsrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

96

Utilisez requests.packages.urllib3.disable_warnings()et verify=Falsesur les requestsméthodes.

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)

11
Votre réponse est utile lorsque vous souhaitez vous débarrasser d'avertissements tels que "Une demande HTTPS non vérifiée est en cours". Mais verify=Falsedoit être présent quand même. Tnx.
Lufa

17
Et pour ne pas cacher tous les avertissements: from urllib3.exceptions import InsecureRequestWarningalorsrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

Pour ceux qui ne peuvent pas désactiver les avertissements, vous pouvez essayer requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Cela fonctionne car il garantit que urllib3.exceptions.InsecureRequestWarningc'est exactement celui utilisé par requests.
AnnieFromTaiwan

32

Pour ajouter à la réponse de Blender , vous pouvez désactiver SSL pour toutes les demandes en utilisantSession.verify = False

import requests

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

Notez que urllib3, (que Requests utilise), décourage fortement de faire des requêtes HTTPS non vérifiées et déclenchera un InsecureRequestWarning.


11

Peut également être fait à partir de la variable d'environnement:

export CURL_CA_BUNDLE=""

1
Cela me donne: "OSError: Impossible de trouver un paquet de certificats TLS CA approprié, chemin non valide:" ". J'utilise la demande 2.22.0
chaim

ouexport REQUESTS_CA_BUNDLE='your-ca.pem'
weaming

1
Cela semble être la meilleure réponse au cas où vous auriez besoin d'utiliser une bibliothèque que vous ne pouvez pas modifier
user989762

Sur la base de CURL_CA_BUNDLE , des os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemœuvres pour Python 3.8.3 lors de l' utilisation 1.24.0 google-nuage-BigQuery et BigQuery client Lib pour Python
SAMM

8

Si vous souhaitez envoyer exactement la demande de publication avec l'option verify = False, le moyen le plus rapide consiste à utiliser ce code:

import requests

requests.api.request('post', url, data={'bar':'baz'}, json=None, verify=False)

Bandit ne sera pas content lorsque vous désactiverez verify = False. Voir: docs.openstack.org/bandit/latest/plugins/…
kRazzy R

Bonjour, j'ai une demande qui me donne la réponse de la demande de message dans le facteur en désactivant la «vérification du certificat SSL» dans l'option de paramétrage. Mais, si j'obtiens le code de demande python fourni par le facteur, je recevrai l'erreur "Routines SSL", "tls_process_server_certificate", "Certificate verify failed" et l'ajout de "verify = False" n'aide pas dans ce cas, est existe-t-il une solution pour obtenir la réponse du facteur dans le script de demande python?
Taha Hamedani
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.