Como desabilito a verificação do certificado de segurança nas solicitações do Python


230

estou usando

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

mas recebo um request.exceptions.SSLError. O site tem um certificado expirado, mas não estou enviando dados confidenciais, portanto, isso não importa para mim. Imagino que exista um argumento como 'verifiy = False' que eu possa usar, mas não consigo encontrá-lo.

Respostas:


411

A partir da documentação :

requeststambém pode ignorar a verificação do certificado SSL se você definir verifycomo Falso.

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

Se você estiver usando um módulo de terceiros e quiser desativar as verificações, aqui está um gerenciador de contexto que aplica os patches requestse os modifica para que verify=Falseseja o padrão e suprima o aviso.

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

Veja como você o 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')

Observe que esse código fecha todos os adaptadores abertos que trataram de uma solicitação corrigida depois que você saiu do gerenciador de contexto. Isso ocorre porque as solicitações mantêm um pool de conexões por sessão e a validação do certificado ocorre apenas uma vez por conexão, para que coisas inesperadas como essa ocorram:

>>> 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
Obrigado, isso funciona se você tiver poucas chamadas de solicitações dentro do seu próprio código, mas imagine que eu quero desabilitar isso em uma terceira biblioteca parcialmente que usa solicitações ... seria impossível corrigir a lib de terceiros assim.
18713

7
@sorin: Basta patch de macaco requestse tem como verifypadrão False.
Blender

2
Como suprimir a grande mensagem de aviso desagradável que ainda é impressa?
Michael Michael

27
@ requests.packages.urllib3.disable_warnings()
Michael

8
@ Michael: ou para evitar esconder todas as advertências: from urllib3.exceptions import InsecureRequestWarningentãorequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

96

Use requests.packages.urllib3.disable_warnings()e verify=Falseem 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)

11
Sua resposta é útil quando você deseja se livrar de avisos como "Solicitação de HTTPS não verificada está sendo feita". Mas verify=Falsedeve estar presente de qualquer maneira. Tnx.
Lufa 27/01

17
E para evitar esconder todas as advertências: from urllib3.exceptions import InsecureRequestWarningentãorequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

Para aqueles que não podem desativar os avisos, você pode tentar requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Isso funciona porque garante que urllib3.exceptions.InsecureRequestWarningé exatamente o usado por requests.
AnnieFromTaiwan

32

Para adicionar à resposta do Blender , você pode desativar o SSL para todas as solicitações usandoSession.verify = False

import requests

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

Observe que urllib3 , (que o Requests usa), desencoraja fortemente a realização de solicitações HTTPS não verificadas e gera uma InsecureRequestWarning.


11

Também pode ser feito a partir da variável de ambiente:

export CURL_CA_BUNDLE=""

1
Isso me dá: "OSError: Não foi possível encontrar um pacote de certificados TLS CA adequado, caminho inválido:" ". Estou usando a solicitação 2.22.0
chaim

ouexport REQUESTS_CA_BUNDLE='your-ca.pem'
weaming 28/11/19

1
Esta parece ser a melhor resposta caso você precise usar uma biblioteca que não pode editar
user989762

Baseado em CURL_CA_BUNDLE , os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemfunciona para o Python 3.8.3 ao usar o google-cloud-bigquery 1.24.0 e o BigQuery Client Lib para Python
samm

8

Se você deseja enviar exatamente uma solicitação de postagem com a opção check = False, a maneira mais rápida é usar este código:

import requests

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

O bandido não ficará feliz quando você desabilitar verificar = Falso. Vejo: docs.openstack.org/bandit/latest/plugins/…
kRazzy R

Olá, Tenho uma solicitação que me fornece a resposta da solicitação de postagem no Postman desativando a 'Verificação de certificado SSL' na opção de configuração. Mas, se eu receber o código de solicitação python fornecido pelo Postman, receberei o erro "Rotinas SSL '', 'tls_process_server_certificate', 'certificado verificação falhou" e adicionar o' confirm = False 'não ajuda neste caso. Existe alguma solução para obter a resposta do Postman no script de solicitação python?
Taha Hamedani
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.