Python isteklerinde güvenlik sertifikası kontrolünü nasıl devre dışı bırakabilirim?


230

Ben kullanıyorum

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

ancak bir request.exceptions.SSLError alıyorum. Web sitesinin süresi dolmuş bir sertifikası var, ancak hassas veriler göndermiyorum, bu yüzden benim için önemli değil. Kullanabileceğim 'verifiy = False' gibi bir argüman olduğunu hayal ederdim, ama bulamıyorum.

Yanıtlar:


412

Gönderen belgeler :

requestsverifyYanlış seçeneğine ayarlarsanız SSL sertifikasının doğrulanmasını da yoksayabilir .

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

Üçüncü taraf bir modül kullanıyorsanız ve denetimleri devre dışı bırakmak istiyorsanız, burada maymun yamaları requestsdeğiştiren verify=Falseve varsayılan olarak uyarıyı engelleyen bir bağlam yöneticisi var .

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

İşte nasıl kullanacağınız:

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

Bu kodun, içerik yöneticisinden ayrıldıktan sonra yamalanmış bir isteği işleyen tüm açık bağdaştırıcıları kapattığını unutmayın. Bunun nedeni, isteklerin oturum başına bağlantı havuzunu tutması ve sertifika doğrulamanın bağlantı başına yalnızca bir kez gerçekleşmesidir, bu nedenle böyle beklenmedik şeyler gerçekleşir:

>>> 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
Teşekkürler, kendi kod içinde birkaç istek çağrıları varsa, ancak bu istekleri kullanan üçüncü bir kısmen kütüphanede devre dışı bırakmak istediğinizi düşünün, bu çalışır ... böyle üçüncü taraf lib düzeltmek mümkün olmaz.
sorin

7
@sorin: Sadece maymun yaması requestsve verifyvarsayılan var False.
Blender

2
Hala yazdırılmakta olan büyük kötü uyarı mesajını nasıl bastırabilirim?
Michael

27
@Michael kendi sorumu cevaplayacak:requests.packages.urllib3.disable_warnings()
Michael

8
@Michael: veya tüm uyarıları gizlemekten kaçınmak için: from urllib3.exceptions import InsecureRequestWarningo zamanrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

96

Kullanım requests.packages.urllib3.disable_warnings()ve verify=Falseüzerinde requestsyöntemlerle.

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
"Doğrulanmamış HTTPS isteği yapılıyor" gibi Uyarılardan kurtulmak istediğinizde cevabınız yararlı olacaktır. Ama verify=Falseyine de mevcut olmalı. Tnx.
Lufa

17
Ve tüm uyarıları gizlemekten kaçınmak için: from urllib3.exceptions import InsecureRequestWarningo zamanrequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

Uyarıları devre dışı bırakamayanlar için deneyebilirsiniz requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Bu, çünkü urllib3.exceptions.InsecureRequestWarningtam olarak kullanılanın olmasını sağlar requests.
AnnieFromTaiwan

32

Blender'ın yanıtına eklemek için şunu kullanarak tüm istekler için SSL'yi devre dışı bırakabilirsiniz:Session.verify = False

import requests

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

Not olduğunu urllib3(kullanımları İstekleri olan), kuvvetle etmemektedir onaylanmamış HTTPS istekleri yapan ve bir yükseltecektir InsecureRequestWarning.


11

Ayrıca ortam değişkeninden yapılabilir:

export CURL_CA_BUNDLE=""

1
Bu bana verir: "OSError: Uygun bir TLS CA sertifika paketi bulunamadı, geçersiz yol:" ". İstek 2.22.0 kullanıyorum
chaim

veyaexport REQUESTS_CA_BUNDLE='your-ca.pem'
weaming

1
Düzenleyemediğiniz bir kitaplığı kullanmanız gerektiğinde bu en iyi yanıt gibi görünüyor
user989762

Dayanarak CURL_CA_BUNDLE , os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemPython 3.8.3 için çalışmalar kullanırken google-bulut BigQuery'yi 1.24.0 ve Python için BigQuery Müşteri Lib
Samm

8

Verify = False seçeneğiyle tam olarak posta isteği göndermek istiyorsanız, en hızlı yol bu kodu kullanmaktır:

import requests

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

Verify = False seçeneğini devre dışı bıraktığınızda eşkıya mutlu olmaz. Bkz. Docs.openstack.org/bandit/latest/plugins/…
kRazzy R

Merhaba, ayar seçeneğindeki 'SSL sertifikası doğrulamasını' devre dışı bırakarak Postacı'da posta isteğine yanıt veren bir isteğim var. Ancak, Postacı tarafından sağlanan python istek kodunu alırsam, "SSL rutinleri", 'tls_process_server_certificate', 'sertifika doğrulama başarısız "hatası alır ve bu durumda' verify = False 'eklenmesi yardımcı olmaz, istek komut dosyasında Postacı yanıt almak için herhangi bir çözüm var mı?
Taha Hamedani
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.