Search code examples
sslpython-requestspython-3.10

How to change/tweak Python 3.10 default SSL settings for requests - sslv3 alert handshake failure


The issue:

Python 3.10 increased the default security settings of the TLS stack. Awesome. I have a legacy application running something that theses settings do not like. I don't know what exactly. How do tweak these settings to let my request through?

The story:

I'm writing a small script to extract some information from a Jazz RTC instance running on premise. It clearly has a... problematic ssl certificate. Nothing that a "verify=False" shouldn't fix. Well, it does not. When I run the following code in python 3.10...

if __name__ == '__main__':

    headers = {'Content-Type': 'application/x-www-form-urlencoded'}

    data = {
        'j_username': username,
        'j_password': password
    }

    result = requests.post(url, data=data, headers=headers, verify=False).json

    print(result)

... i get this handshake error.

requests.exceptions.SSLError: HTTPSConnectionPool(host='...', port=...): Max retries exceeded with url: /ccm/authenticated/j_security_check (Caused by SSLError(SSLError(1, '[SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:997)'))

BUT, it works without a problem on Python 3.9. Looking around for an answer, I found out about the heightened security defaults added to python 3.10, like this question... but nothing on how to tweak them to make this work with my requests.

The details:

This is what the browser developer tools report

  • As usual, this is a very limited enterprise environment. I can't do much. No admin privileges.
  • The department responsible for that host, as expected, says it can't be fixed, giving some shallow excuses.
  • "If it works on 3.9, why not use it?" - Well, several reasons. The major one being 3.10 is the version accepted for use in the company environment. If they even find out I sneaked in a conda 3.9 venv to test stuff, I'll get a mean lecture.

Any help is appreciated! o/


Solution

  • @PatrickMevzek 's comment led me to other queries and this question.

    Which showed me how to change the used ciphers AND security level. The following snippet from @bgoeman worked for my environment:

    import urllib3
    requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL:@SECLEVEL=1'
    

    Obviously, in general THIS SHOULD NOT BE USED. This will allow for man-in-the-middle attacks and other nasty things. Be careful and mindful when changing these settings.