Làm cách nào để vô hiệu hóa kiểm tra chứng chỉ bảo mật trong các yêu cầu Python


230

tôi đang dùng

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

nhưng tôi nhận được một request.exceptions.SSLError. Trang web đã có chứng nhận hết hạn, nhưng tôi không gửi dữ liệu nhạy cảm, vì vậy nó không quan trọng với tôi. Tôi sẽ tưởng tượng có một đối số như 'verifiy = Sai' mà tôi có thể sử dụng, nhưng dường như tôi không thể tìm thấy nó.

Câu trả lời:


411

Từ tài liệu :

requestscũng có thể bỏ qua việc xác minh chứng chỉ SSL nếu bạn đặt verifythành Sai.

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

Nếu bạn đang sử dụng mô-đun của bên thứ ba và muốn vô hiệu hóa kiểm tra, thì đây là trình quản lý bối cảnh mà khỉ vá requestsvà thay đổi nó để verify=Falsemặc định và loại bỏ cảnh báo.

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

Đây là cách bạn sử dụng nó:

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

Lưu ý rằng mã này sẽ đóng tất cả các bộ điều hợp mở đã xử lý một yêu cầu được vá khi bạn rời khỏi trình quản lý bối cảnh. Điều này là do các yêu cầu duy trì nhóm kết nối mỗi phiên và xác thực chứng chỉ chỉ xảy ra một lần cho mỗi kết nối nên những điều không mong muốn như thế này sẽ xảy ra:

>>> 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
Cảm ơn, điều này hoạt động nếu bạn có một vài cuộc gọi yêu cầu bên trong mã của riêng bạn, nhưng hãy tưởng tượng rằng tôi muốn vô hiệu hóa điều này trong thư viện một phần thứ ba sử dụng các yêu cầu, ... sẽ không thể sửa lib của bên thứ 3 như thế này.
sorin

7
@sorin: Chỉ cần vá khỉ requestsvà có verifymặc định False.
Máy xay sinh tố

2
Làm cách nào để chặn thông điệp cảnh báo khó chịu lớn vẫn được in?
Michael

27
@Michael để trả lời câu hỏi của riêng tôi:requests.packages.urllib3.disable_warnings()
Michael

8
@Michael: hoặc để tránh ẩn tất cả các cảnh báo: from urllib3.exceptions import InsecureRequestWarningsau đórequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

96

Sử dụng requests.packages.urllib3.disable_warnings()verify=Falsetrên requestsphương pháp.

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
Câu trả lời của bạn rất hữu ích khi bạn muốn loại bỏ các Cảnh báo như "Yêu cầu HTTPS chưa được xác minh đang được thực hiện". Nhưng verify=Falsedù sao cũng phải có mặt. Tnx.
Lufa

17
Và để tránh ẩn tất cả các cảnh báo: from urllib3.exceptions import InsecureRequestWarningsau đórequests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
Sébastien Deprez

Đối với những người không thể vô hiệu hóa cảnh báo, bạn có thể thử requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning). Điều này hoạt động bởi vì nó đảm bảo urllib3.exceptions.InsecureRequestWarninglà chính xác được sử dụng bởi requests.
AnnieFromTaiwan

32

Để thêm vào câu trả lời của Blender , bạn có thể tắt SSL cho tất cả các yêu cầu bằng cách sử dụngSession.verify = False

import requests

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

Lưu ý rằng urllib3, (mà Yêu cầu sử dụng), không khuyến khích mạnh mẽ thực hiện các yêu cầu HTTPS chưa được xác minh và sẽ đưa ra một InsecureRequestWarning.


11

Cũng có thể được thực hiện từ biến môi trường:

export CURL_CA_BUNDLE=""

1
Điều này mang lại cho tôi: "OSError: Không thể tìm thấy gói chứng chỉ TLS CA phù hợp, đường dẫn không hợp lệ:" ". Tôi đang sử dụng yêu cầu 2.22.0
chaim

hoặcexport REQUESTS_CA_BUNDLE='your-ca.pem'
thúc

1
Đây dường như là câu trả lời tốt nhất trong trường hợp bạn cần sử dụng thư viện mà bạn không thể chỉnh sửa
user989762

Dựa trên CURL_CA_BUNDLE , os.environ['REQUESTS_CA_BUNDLE'] = 'FiddlerRootCertificate_Base64_Encoded_X.509.cer.pem' # your-ca.pemhoạt động cho Python 3.8.3 khi sử dụng google-cloud-bigquery 1.24.0BigQuery Client Lib cho Python
samm

8

Nếu bạn muốn gửi chính xác yêu cầu bài đăng với tùy chọn verify = false, cách nhanh nhất là sử dụng mã này:

import requests

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

Tên cướp sẽ không vui khi bạn tắt xác minh = Sai. Xem: docs.openstack.org/bandit/latest/plugins/ từ
kRazzy R

Xin chào, tôi có một yêu cầu cung cấp cho tôi phản hồi của yêu cầu bài trong Người đưa thư bằng cách vô hiệu hóa 'Xác minh chứng chỉ SSL' trong tùy chọn cài đặt. Nhưng, nếu tôi nhận được mã yêu cầu python do Người đưa thư cung cấp, tôi sẽ nhận được "các thói quen SSL ',' tls_ process_server_cert ve ',' xác minh lỗi 'và thêm lỗi' verify = false 'không giúp ích gì trong trường hợp này Có giải pháp nào để nhận được phản hồi của Người đưa thư trong tập lệnh yêu cầu python không?
Taha Hamedani
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.