-
-
Notifications
You must be signed in to change notification settings - Fork 10k
Add troubleshooting guidance for SSL verification errors #7556
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -251,6 +251,152 @@ during local development or testing. | |
|
|
||
| By default, ``verify`` is set to True. Option ``verify`` only applies to host certs. | ||
|
|
||
| Security Implications of Disabling SSL Verification (``verify=False``) | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| - Man-in-the-middle (MitM) attacks are a form of active eavesdropping | ||
| in which the attacker intercepts or impersonates the server, especially | ||
| on public networks. | ||
|
|
||
| - Data exposure, where all data transmitted over the network can be | ||
| intercepted and read by the attacker. This includes sensitive information | ||
| such as login credentials, personal data and financial information. | ||
|
|
||
| - Regulatory and compliance issues with regulations like SOC 2 and | ||
| GDPR regarding data security and privacy. Disabling SSL verification | ||
| can lead to non-compliance with these regulations, resulting in legal | ||
| consequences and reputational damage. | ||
|
|
||
| When ``verify=False`` may be useful | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| - Local development on localhost with a self-signed certificate. Never use | ||
| ``verify=False`` in production or with sensitive data. | ||
|
|
||
| - Testing against a server with a self-signed certificate. | ||
|
|
||
| - Internal or isolated networks where you control both the server | ||
| and the client. | ||
|
|
||
| - Short-term debugging of an issue with an endpoint, to isolate the problem | ||
| without worrying about SSL verification. | ||
|
|
||
| Even in these cases, it's recommended to pass the path to the certificate | ||
| for validation instead of disabling SSL verification. | ||
| ``verify='/path/to/certfile'`` is better because it allows you to | ||
| validate the server's certificate against a known trusted certificate, | ||
| providing a higher level of security than disabling verification entirely. | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, you've just generated way more words than what was already said above adding no value |
||
| Troubleshooting SSL Verification Errors | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the only section actually requested. |
||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
|
|
||
| Common causes: | ||
|
|
||
| - Outdated or missing CA certificates on the client machine. | ||
| Requests trust the CAs shipped by the ``certifi`` package, which | ||
| may be old or may not include the CA that signed the server's certificate. | ||
|
Comment on lines
+295
to
+297
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Outdated" is unlikely. CAs are not added that frequently to the bundle. When CAs expire, they can stay in the bundle. It's not likely that. It's most likely someone using an expired certificate, a self-signed certificate, or a CA that's not a public CA (e.g., internal PKI implementations). You've added lots and lots of text here that's not addressing the most common problems. |
||
|
|
||
| - Self-signed certificate where Python will fail to verify unless manually | ||
| configured in development or staging environment. This should be avoided in | ||
| production environments, and a CA-signed certificate should be used instead. | ||
|
|
||
| - Time synchronization issues. Incorrect system time or date on the client | ||
| machine or server may cause verification failures. | ||
|
|
||
| - Firewall or proxy intercepting SSL traffic and presenting its own certificate | ||
| will trigger verification errors unless the proxy's certificate is installed on | ||
| the client machine or configured to be trusted. | ||
|
|
||
| - Incomplete certificate chain where the server does not provide the full chain of | ||
| trust, causing verification failures. The server should be configured to provide the | ||
| full certificate chain. | ||
|
|
||
| - Old Python version or OpenSSL library that does not support modern TLS protocols. | ||
|
|
||
| - An expired certificate on the server. The server's certificate may have expired, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's no example of what this would look like as an error and it's easily the most common one. |
||
| causing verification failures. | ||
|
|
||
| - Hostname mismatch where the server's certificate does not match the hostname being | ||
| accessed. This can happen if the server is misconfigured or if a different hostname is | ||
| used to access the server.This may look like this:: | ||
|
|
||
| requests.exceptions.SSLError: hostname 'kennethreitz.org' doesn't match either of 'kennethreitz.com', 'kennethreitz.net'. | ||
|
|
||
|
|
||
|
|
||
| Diagnosing the problem can be done by following these steps: | ||
|
Comment on lines
+324
to
+327
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why so many new lines? Oh this is "AI" drivel. Might as well stop reviewing now. You put zero real effort into reviewing this at all eh? |
||
|
|
||
|
|
||
| 1. Read the full error message. ``SSLError`` usually names the underlying cause, such as | ||
| ``self signed certificate``, ``CERTIFICATE_VERIFY_FAILED``, ``certificate has expired`` | ||
| or ``hostname ... doesn't match``. | ||
|
|
||
| 2. Use OpenSSL to inspect the certificate the server presents:: | ||
|
|
||
| $ openssl s_client -connect kennethreitz.org:443 -servername kennethreitz.org | ||
|
|
||
| Look at the returned certificate chain and the ``Verify return code`` line at the end. | ||
| ``Verify return code: 0 (ok)`` means the chain is trusted. A non-zero code identifies | ||
| the problem, for example:: | ||
|
|
||
| Verify return code: 18 (self signed certificate) | ||
|
|
||
| 3. Ensure the system time and date are correct on the client machine and server. A certificate is usually valid for a specific time period, and | ||
| time synchronization issues can cause verification failures. Error messages may be ``SSL Certificate is not yet valid``, | ||
| ``SSL Certificate has expired``, ``NET::ERR_CERT_DATE_INVALID``, and ``SEC_ERROR_EXPIRED_CERTIFICATE``. | ||
| These error messages indicate that the certificate is not valid due to the validity period. If the clocks are okay then the certificate may | ||
| have expired and needs to be renewed. | ||
|
|
||
|
|
||
| Once you know an error has occurred, it can be resolved by following these steps: | ||
|
|
||
|
|
||
| 1. Update your CA bundle since this is a common issue:: | ||
|
|
||
| $ python -m pip install --upgrade certifi | ||
|
|
||
| :: | ||
|
|
||
| >>> import requests | ||
| >>> import certifi | ||
| >>> response = requests.get('https://kennethreitz.org', verify=certifi.where()) | ||
| >>> print(response.status_code) | ||
| 200 | ||
|
|
||
| 2. If the server uses a self-signed or privately signed certificate, download it and save it | ||
| locally (usually in ``.crt`` or ``.pem`` format) then pass the path to ``verify`` instead of | ||
| disabling verification:: | ||
|
|
||
| >>> import requests | ||
| >>> requests.get('https://kennethreitz.org', verify='/path/to/server.crt') | ||
|
|
||
| You can also trust this certificate by adding it to your system's trusted CA store, or by using | ||
| the ``REQUESTS_CA_BUNDLE`` environment variable to point to a custom CA bundle that includes the server's certificate. | ||
|
|
||
|
|
||
| 3. Upgrade your Python version and OpenSSL library to support modern TLS protocols producing handshake failures that resemble certification verification errors. | ||
| For example, TLSv1.0 and TLSv1.1 are deprecated and may not be supported by the server, causing handshake failures. | ||
|
|
||
| 4. Correct the system clock if diagnosis pointed to time synchronization issues and the certificate is not actually expired. | ||
| The best fix is to sync the machine's time automatically instead of setting it by hand:: | ||
|
|
||
| #Linux | ||
| $ sudo apt install ntp | ||
| $ sudo timedatectl set-ntp true | ||
|
|
||
| #macOS | ||
| $ sudo sntp -sS time.apple.com | ||
|
|
||
| #Windows (requires admin privileges and automatic time sync enabled) | ||
| >w32tm /resync | ||
|
|
||
| You can retry the request after correcting the system clock to see if the SSL verification error is resolved. | ||
|
|
||
| 5. If you are behind a corporate firewall or proxy, check with your IT department to see if they | ||
| are intercepting SSL traffic and presenting their own certificate. You may need to install the | ||
| proxy's certificate on your client machine or configure your requests to trust the proxy's | ||
| certificate by passing its path to ``verify``. This has been demonstrated in step 2. Look at :ref:`proxies`. | ||
|
|
||
| Client Side Certificates | ||
| ------------------------ | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary. You're repeating what's already said above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah that's true, thanks for pointing that out.