¿Cómo deshabilito la verificación del certificado de seguridad en las solicitudes de Python?

230

estoy usando

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

pero recibo una request.exceptions.SSLError. El sitio web tiene un certificado caducado, pero no estoy enviando datos confidenciales, por lo que no me importa. Me imagino que hay un argumento como 'verifiy = False' que podría usar, pero parece que no puedo encontrarlo.

Paul Draper
fuente

Respuestas:

411

De la documentación :

requestsTambién puede ignorar la verificación del certificado SSL si establece verifyFalse.

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

Si está utilizando un módulo de terceros y desea deshabilitar las comprobaciones, aquí hay un administrador de contexto que requestsmodifica los parches y los cambia para que verify=Falsesea ​​el predeterminado y suprima la advertencia.

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

Así es como lo usa:

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

Tenga en cuenta que este código cierra todos los adaptadores abiertos que manejan una solicitud parcheada una vez que abandona el administrador de contexto. Esto se debe a que las solicitudes mantienen un grupo de conexiones por sesión y la validación del certificado ocurre solo una vez por conexión, por lo que sucederán cosas inesperadas como esta:

>>> 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]>
Licuadora
fuente
66
Gracias, esto funciona si tiene pocas llamadas de solicitudes dentro de su propio código, pero imagine que quiero deshabilitar esto en una tercera biblioteca en parte que usa solicitudes, ... sería imposible arreglar la biblioteca de terceros de esta manera.
sorin
77
@sorin: solo parche mono requestsy por verifydefecto tiene False.
Blender
2
¿Cómo suprimo el gran mensaje de advertencia desagradable que todavía se imprime?
Michael
27
@Michael para responder mi propia pregunta:requests.packages.urllib3.disable_warnings()
Michael
8
@Michael: o para evitar ocultar todas las advertencias: from urllib3.exceptions import InsecureRequestWarningentoncesrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez
96

Uso requests.packages.urllib3.disable_warnings()y verify=Falsesobre requestsmétodos.

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
fuente
11
Su respuesta es útil cuando desea deshacerse de advertencias como "Se está realizando una solicitud HTTPS no verificada". Pero verify=Falsedebe estar presente de todos modos. Tnx.
Lufa
17
Y para evitar ocultar todas las advertencias: from urllib3.exceptions import InsecureRequestWarningentoncesrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez
Para aquellos que no pueden desactivar las advertencias, puede intentarlo requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Esto funciona porque asegura que urllib3.exceptions.InsecureRequestWarninges el exacto utilizado por requests.
AnnieFromTaiwan
32

Para agregar a la respuesta de Blender , puede deshabilitar SSL para todas las solicitudes usandoSession.verify = False

import requests

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

Tenga en cuenta que urllib3, (que utiliza Solicitudes), desaconseja hacer solicitudes HTTPS no verificadas y generará un InsecureRequestWarning.

Stevoisiak
fuente
11

También se puede hacer desde la variable de entorno:

export CURL_CA_BUNDLE=""
Stan Gabenov
fuente
1
Esto me da: "OSError: No se pudo encontrar un paquete de certificado TLS CA adecuado, ruta no válida:" ". Estoy usando la solicitud 2.22.0
chaim
oexport REQUESTS_CA_BUNDLE='your-ca.pem'
Weaming
1
Esta parece ser la mejor respuesta en caso de que necesite usar una biblioteca que no puede editar
user989762
Basado en CURL_CA_BUNDLE , os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemfunciona para Python 3.8.3 cuando se utiliza google-cloud-bigquery 1.24.0 y BigQuery Client Lib para Python
sábado
8

Si desea enviar exactamente la solicitud de publicación con la opción de verificación = Falso, la forma más rápida es usar este código:

import requests

requests.api.request('post', url, data={'bar':'baz'}, json=None, verify=False)
Ruslan Khyurri
fuente
Bandit no estará contento cuando deshabilite verificar = Falso. Ver: docs.openstack.org/bandit/latest/plugins/…
kRazzy R
Hola, tengo una solicitud que me da la respuesta de la solicitud de publicación en el Cartero deshabilitando la 'verificación de certificado SSL' en la opción de configuración. Pero, si obtengo el código de solicitud de Python proporcionado por el cartero, recibiré el error "rutinas SSL", "tls_process_server_certificate", "certificado verificado falló" y agregar el "verificar = Falso" no ayuda en este caso, es ¿Hay alguna solución para obtener la respuesta del cartero en el script de solicitud de Python?
Taha Hamedani