Bagaimana cara menonaktifkan pemeriksaan sertifikat keamanan dalam permintaan Python

230

saya menggunakan

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

tapi saya mendapat permintaan. pengecualian. Kesalahan. Situs web memiliki sertifikat kedaluwarsa, tetapi saya tidak mengirim data sensitif, jadi tidak masalah bagi saya. Saya akan membayangkan ada argumen seperti 'verifikasi = Salah' yang dapat saya gunakan, tetapi sepertinya saya tidak dapat menemukannya.

Paul Draper
sumber

Jawaban:

411

Dari dokumentasi :

requestsjuga dapat mengabaikan memverifikasi sertifikat SSL jika Anda menetapkan verifyke False.

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

Jika Anda menggunakan modul pihak ketiga dan ingin menonaktifkan pemeriksaan, inilah manajer konteks yang menambal monyet requestsdan mengubahnya sehingga verify=Falsemerupakan default dan menekan peringatan.

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

Begini cara Anda menggunakannya:

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

Perhatikan bahwa kode ini menutup semua adapter terbuka yang menangani permintaan yang ditambal setelah Anda meninggalkan manajer konteks. Ini karena permintaan mempertahankan kumpulan koneksi per sesi dan validasi sertifikat hanya terjadi sekali per koneksi sehingga hal-hal tak terduga seperti ini akan terjadi:

>>> 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]>
Blender
sumber
6
Terima kasih, ini berfungsi jika Anda memiliki beberapa permintaan panggilan di dalam kode Anda sendiri, tetapi bayangkan bahwa saya ingin menonaktifkan ini di perpustakaan sebagian ketiga yang menggunakan permintaan, ... tidak mungkin untuk memperbaiki lib pihak ke-3 seperti ini.
sorin
7
@sorin: Hanya tambalan monyet requestsdan memiliki verifystandar untuk False.
Blender
2
Bagaimana cara saya menekan pesan peringatan besar yang masih dicetak?
Michael
27
@Michael untuk menjawab pertanyaan saya sendiri:requests.packages.urllib3.disable_warnings()
Michael
8
@Michael: atau untuk menghindari menyembunyikan semua peringatan: from urllib3.exceptions import InsecureRequestWarninglalurequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez
96

Gunakan requests.packages.urllib3.disable_warnings()dan verify=Falsepada requestsmetode.

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
sumber
11
Jawaban Anda berguna ketika Anda ingin menyingkirkan Peringatan seperti "Permintaan HTTPS tidak diverifikasi sedang dibuat". Tetapi verify=Falseharus tetap hadir. Tnx.
Lufa
17
Dan untuk menghindari menyembunyikan semua peringatan: from urllib3.exceptions import InsecureRequestWarninglalurequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez
Bagi mereka yang tidak dapat menonaktifkan peringatan, Anda dapat mencoba requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Ini berfungsi karena memastikan urllib3.exceptions.InsecureRequestWarningyang tepat digunakan oleh requests.
AnnieFromTaiwan
32

Untuk menambahkan jawaban Blender , Anda dapat menonaktifkan SSL untuk semua permintaan menggunakanSession.verify = False

import requests

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

Perhatikan bahwa urllib3, (yang Digunakan oleh Permintaan), sangat tidak menyarankan untuk membuat permintaan HTTPS yang tidak terverifikasi dan akan memunculkan InsecureRequestWarning.

Stevoisiak
sumber
11

Juga dapat dilakukan dari variabel lingkungan:

export CURL_CA_BUNDLE=""
Stan Gabenov
sumber
1
Ini memberi saya: "OSError: Tidak dapat menemukan bundel sertifikat TLS CA yang cocok, jalur tidak valid:" ". Saya menggunakan permintaan 2.22.0
chaim
atauexport REQUESTS_CA_BUNDLE='your-ca.pem'
weaming
1
Ini tampaknya menjadi jawaban terbaik jika Anda perlu menggunakan perpustakaan yang tidak dapat Anda edit
user989762
Berdasarkan CURL_CA_BUNDLE , os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemberfungsi untuk Python 3.8.3 saat menggunakan google-cloud-bigquery 1.24.0 dan BigQuery Client Lib untuk Python
samm
8

Jika Anda ingin mengirim permintaan posting persis dengan verifikasi = opsi Salah, cara tercepat adalah dengan menggunakan kode ini:

import requests

requests.api.request('post', url, data={'bar':'baz'}, json=None, verify=False)
Ruslan Khyurri
sumber
Bandit tidak akan senang ketika Anda menonaktifkan verifikasi = Salah. Lihat: docs.openstack.org/bandit/latest/plugins/…
kRazzy R
Halo, saya punya permintaan yang memberi saya respons permintaan pos di tukang pos dengan menonaktifkan 'verifikasi sertifikat SSL' di opsi pengaturan. Tetapi, jika saya mendapatkan kode permintaan python yang disediakan oleh tukang pos, saya akan menerima "rutinitas SSL ',' tls_process_server_certificate ',' verifikasi sertifikat gagal" kesalahan dan menambahkan kesalahan 'verifikasi = Salah' tidak membantu dalam kasus ini, Apakah ada solusi untuk mendapatkan respons dari tukang pos di skrip permintaan python?
Taha Hamedani