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.

Paul Draper
la source

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]>
Mixeur
la source
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)
efrenfuentes
la source
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.

Stevoisiak
la source
11

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

export CURL_CA_BUNDLE=""
Stan Gabenov
la source
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)
Ruslan Khyurri
la source
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