Closed urbanogilson closed 2 months ago
A handshake error is not the same as verifying a trust chain. My guess is that requests/urllib3 and your server cannot agree on ciphersuites to use during the handshake. Otherwise you would see a very different exception message.
From https://www.ssllabs.com/ssltest the supported cipher suites:
Protocols TLS 1.3 No TLS 1.2 Yes TLS 1.1 Yes TLS 1.0 Yes SSL 3 No SSL 2 No Cipher Suites # TLS 1.2 (suites in server-preferred order) TLS_RSA_WITH_AES_256_CBC_SHA256 (0x3d) WEAK 256 TLS_RSA_WITH_AES_256_CBC_SHA (0x35) WEAK 256 TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d) WEAK 256 TLS_RSA_WITH_AES_128_CBC_SHA256 (0x3c) WEAK 128 TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) WEAK 128 TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) WEAK 128 # TLS 1.1 (suites in server-preferred order) TLS_RSA_WITH_AES_256_CBC_SHA (0x35) WEAK 256 TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) WEAK 128 # TLS 1.0 (suites in server-preferred order) TLS_RSA_WITH_AES_256_CBC_SHA (0x35) WEAK 256 TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) WEAK 128
Yeah, the only cipher suites this site offers are awful, and I suspect that if you do the following:
from urllib3.util.ssl_ import create_urllib3_context
for item in create_urllib3_context().get_ciphers():
print(item['name'])
I would suggest trying the following:
import urllib3
http = urllib3.PoolManager()
response = http.request('GET', 'https://...', ca_certs="CERT_NONE")
I expect you'll encounter the same issue.
You are right, it is reproducible using urllib3
from urllib3.util.ssl_ import create_urllib3_context
for item in create_urllib3_context().get_ciphers():
print(item['name'])
TLS_AES_256_GCM_SHA384
TLS_CHACHA20_POLY1305_SHA256
TLS_AES_128_GCM_SHA256
ECDHE-ECDSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-GCM-SHA384
ECDHE-ECDSA-AES128-GCM-SHA256
ECDHE-RSA-AES128-GCM-SHA256
ECDHE-ECDSA-CHACHA20-POLY1305
ECDHE-RSA-CHACHA20-POLY1305
ECDHE-ECDSA-AES256-SHA384
ECDHE-RSA-AES256-SHA384
ECDHE-ECDSA-AES128-SHA256
ECDHE-RSA-AES128-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES256-SHA256
DHE-RSA-AES128-SHA256
http = urllib3.PoolManager(ca_certs=None)
response = http.request('GET', 'https://website')
Traceback (most recent call last):
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 467, in _make_request
self._validate_conn(conn)
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 1092, in _validate_conn
conn.connect()
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connection.py", line 635, in connect
sock_and_verified = _ssl_wrap_socket_and_match_hostname(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connection.py", line 776, in _ssl_wrap_socket_and_match_hostname
ssl_sock = ssl_wrap_socket(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 466, in ssl_wrap_socket
ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/util/ssl_.py", line 510, in _ssl_wrap_socket_impl
return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
File "/usr/local/lib/python3.10/ssl.py", line 513, in wrap_socket
return self.sslsocket_class._create(
File "/usr/local/lib/python3.10/ssl.py", line 1071, in _create
self.do_handshake()
File "/usr/local/lib/python3.10/ssl.py", line 1342, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 790, in urlopen
response = self._make_request(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 491, in _make_request
raise new_e
urllib3.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/_request_methods.py", line 110, in request
return self.request_encode_url(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/_request_methods.py", line 143, in request_encode_url
return self.urlopen(method, url, **extra_kw)
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/poolmanager.py", line 443, in urlopen
response = conn.urlopen(method, u.request_uri, **kw)
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 874, in urlopen
return self.urlopen(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 874, in urlopen
return self.urlopen(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 874, in urlopen
return self.urlopen(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/connectionpool.py", line 844, in urlopen
retries = retries.increment(
File "/home/vscode/.local/lib/python3.10/site-packages/urllib3/util/retry.py", line 515, in increment
raise MaxRetryError(_pool, url, reason) from reason # type: ignore[arg-type]
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='websitw', port=443): Max retries exceeded with url: / (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:1007)')))
Yeah and as you can see the ciphers that are default on your system (because the version of urllib3 you're using relies on system defaults) don't overlap with the very weak set offered by your server. You can customize the ciphers in creating the context for urllib3 and create a custom requests adapter to work around this but this is not a bug. Using the default ciphers is a good security practice and we will not be modifying things to make default ciphers accept weaker algorithms
Requests is not ignoring the SSL certificate verification when using the
verify=False
option.Expected Result
Same as curl with
-k
or
Actual Result
The result is similar to curl without
-k
.Reproduction Steps
or
System Information
Tested in two systems
Note: URL and IP were masked to
https://website
and255.255.255.255
respectively