urllib, ssl, requests, zeep Client SSL connection to URL fail even with session.verify=false

94 Views Asked by At

I am trying to make a zeep.Client(wsdl_url, transport) to get the wsdl of a webservice. I`ve virtually seen every question on SO and also checked google for a lot of content. None of them seems to help. It seems to be a recent problem with those libraries. I am using:

wsdl_url=https://unsafewebsite.com

Chrome security tab overview

pyOpenSSL==23.2.0
requests==2.31.0
urllib3==2.0.6
zeep==4.2.1

First, I used nmap to get the wsdl_url ciphers using: nmap --script ssl-enum-ciphers -p 443 wsdl_url. It returned:

PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       Key exchange (dh 1024) of lower strength than certificate key
|   TLSv1.1:
|     ciphers:
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       Key exchange (dh 1024) of lower strength than certificate key
|   TLSv1.2:
|     ciphers:
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA (dh 1024) - A
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (dh 1024) - A
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|     compressors:
|       NULL
|     cipher preference: server
|     warnings:
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       Key exchange (dh 1024) of lower strength than certificate key
|_  least strength: D

Nmap done: 1 IP address (1 host up) scanned in 5.58 seconds

First, I tried to make a CustomCipherAdapter(HTTPAdapter), like so:

import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context

CIPHERS = (
    "DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:"
    "DHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:"
    "DHE-RSA-AES256-SHA256:DHE-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:"
    "AES256-GCM-SHA384:AES128-SHA:AES128-SHA256:AES256-SHA:AES256-SHA256:"
    "DES-CBC3-SHA"
    "ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:"
    "DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:"
    "!eNULL:!MD5"
)


class CustomCipherAdapter(HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=CIPHERS)
        kwargs["ssl_context"] = context
        return super(CustomCipherAdapter, self).init_poolmanager(*args, **kwargs)

    def proxy_manager_for(self, *args, **kwargs):
        context = create_urllib3_context(ciphers=CIPHERS)
        kwargs["ssl_context"] = context
        return super(CustomCipherAdapter, self).proxy_manager_for(*args, **kwargs)

And then I initialize my session object and use cert.pem and key.pem to set my client certificate to use with session, also, i set session.verify = False, like so:

session = Session()
session.verify = False
session.cert = (cert.pem, key.pem)

After that, I would simply need to create a zeep.transport Transport and a Client, so that I could consume the wsdl_url, just like this:

# Create a SOAP client with the session
transport = Transport(session=session)
client = Client(wsdl_url, transport=transport)

I had no success. This will yield the following error:

Traceback (most recent call last):
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 467, in _make_request
    self._validate_conn(conn)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 1092, in _validate_conn
    conn.connect()
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connection.py", line 642, in connect
    sock_and_verified = _ssl_wrap_socket_and_match_hostname(
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connection.py", line 783, in _ssl_wrap_socket_and_match_hostname
    ssl_sock = ssl_wrap_socket(
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\util\ssl_.py", line 469, in ssl_wrap_socket
    ssl_sock = _ssl_wrap_socket_impl(sock, context, tls_in_tls, server_hostname)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\util\ssl_.py", line 513, in _ssl_wrap_socket_impl
    return ssl_context.wrap_socket(sock, server_hostname=server_hostname)
  File "C:\Users\usr\AppData\Local\Programs\Python\Python310\lib\ssl.py", line 513, in wrap_socket
    return self.sslsocket_class._create(
  File "C:\Users\usr\AppData\Local\Programs\Python\Python310\lib\ssl.py", line 1071, in _create
    self.do_handshake()
  File "C:\Users\usr\AppData\Local\Programs\Python\Python310\lib\ssl.py", line 1342, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 790, in urlopen
    response = self._make_request(
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 491, in _make_request
    raise new_e
urllib3.exceptions.SSLError: [SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\adapters.py", line 486, in send
    resp = conn.urlopen(
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\urllib3\connectionpool.py", line 844, in urlopen
    retries = retries.increment(
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\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='unsafewebsite.com', port=443): Max retries exceeded with url: endpointOfUnsafeWebsite (Caused by SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)')))        

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\.iagre\iagre\go.py", line 237, in <module>
    client = Client(wsdl_url, transport=transport, plugins=[MyLoggingPlugin()])
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\client.py", line 76, in __init__
    self.wsdl = Document(wsdl, self.transport, settings=self.settings)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\wsdl\wsdl.py", line 92, in __init__
    self.load(location)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\wsdl\wsdl.py", line 95, in load
    document = self._get_xml_document(location)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\wsdl\wsdl.py", line 155, in _get_xml_document
    return load_external(
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\loader.py", line 89, in load_external
    content = transport.load(url)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\transports.py", line 123, in load
    content = self._load_remote_data(url)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\zeep\transports.py", line 135, in _load_remote_data
    response = self.session.get(url, timeout=self.load_timeout)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "C:\Users\usr\.virtualenvs\iagre-hbEl5ufs\lib\site-packages\requests\adapters.py", line 517, in send
    raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='unsafewebsite.com', port=443): Max retries exceeded with url: endpointOfUnsafeWebsite (Caused by SSLError(SSLError(1, '[SSL: DH_KEY_TOO_SMALL] dh key too small (_ssl.c:997)')))

Have anyone experienced such error using zeep, and how can i correct it? Also is important to note that i cant even do requests.get(wsdl_url, cert=(cert,key)). It will yield the same error. So I guess it is a problem related to urllib3, ssl, and requests library, not zeep...

0

There are 0 best solutions below