Forcing TLS1+ in Python’s urllib2 on OSX

The recently-announced POODLE SSLv3 downgrade vulnerability is probably prompting you to update at the very least your client-side TLS applications to negotiate only TLS1 and above. If you’re using Python’s urllib2, however, you may discover that you have little immediate control over the supported TLS dialects. Worse, if you’re on OSX you will discover that urllib2 requests are rejected by servers that have been patched to support only TLS1+. Misery!

The problem appears to stem from the implementation of the SSLv23 compatibility protocol used by Python on OSX, which in wire traces leads with an SSL2 version in the ClientHello, and fails to retry with a higher version if rejected by the server. The upshot is that turning off SSLv3 support is going to break Python client applications that use urllib2 on OSX.

Despite the lack of an explicit interface to do so, forcing TLS1+ support in urllib2 is a reasonably straightforward matter of overriding the default HTTPSHandler and its underlying httplib.HTTPSConnection:

The implementation is somewhat unsatisfying: HTTPSConnection is not designed for extension and this approach requires duplicating the default connect method’s functionality, but it does work.

5 thoughts on “Forcing TLS1+ in Python’s urllib2 on OSX

  1. Hi, I tried it in python 2.6.6
    It is saying:
    AttributeError: TLS1Connection instance has no attribute ‘source_address’
    Any idea?

    • Hi, Sorry. I got it work by myself by removing source_address as it is an optional parameter. Cheers.

    • Sorry, missed your question morgan; this is indeed tailored to the OSX implementation that takes the `source_address` parameter. Glad you figured it out.

  2. Sorry for the questions of a complete newbee:
    Do this supposed to be added to the urllib2.py file, and if yes does it matter where?

  3. Amazing! I’ve faced the same issue on Windows,with Python 2.7 and your solution worked for me too! Thanks a lot!

Comments are closed.