[Python-Dev] Let's make the SSL module sane (original) (raw)

Christian Heimes christian at python.org
Sat Sep 10 10:22:57 EDT 2016


Hi,

(CC TLS gurus)

For 3.6 I like to make the SSL more sane and more secure by default. Yes, I'm a bit late but all my proposals are implemented, documented, partly tested and existing tests are passing. I'm going to write more tests and documentation after beta1.

First I like to deprecated some old APIs and favor of SSLCotext. We have multiple ways to create a SSL socket or to configure libraries like urllib. The general idea is to make SSLContext the central object for TLS/SSL configuration. My patch deprecates ssl.wrap_socket() and SSLSocket constructor in favor of SSLContext.wrap_socket(). The patch also deprecates certfile, keyfile an similar arguments in network protocol libraries.

I also considered to make cert validation enabled by default for all protocol in 3.6, Victor has rising some concerns. How about we change the behavior in 3.7 and just add a warning to 3.6?

http://bugs.python.org/issue28022 https://github.com/tiran/cpython/commits/feature/feature/ssl_deprecation


Next up SSLContext default configuration. A bare SSLContext comes with insecure default settings. I'd like to make SSLContext(PROTOCOL_SSLv23) secure bu default. Changelog: The context is created with more secure default values. The options OP_NO_COMPRESSION, OP_CIPHER_SERVER_PREFERENCE, OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE, OP_NO_SSLv2 (except for PROTOCOL_SSLv2), and OP_NO_SSLv3 (except for PROTOCOL_SSLv3) are set by default. The initial cipher suite list contains only HIGH ciphers, no NULL ciphers and MD5 ciphers (except for PROTOCOL_SSLv2).

http://bugs.python.org/issue28043 https://github.com/tiran/cpython/commits/feature/ssl_sane_defaults


Finally (and this is the biggest) I like to change how the protocols work. OpenSSL 1.1.0 has deprecated all version specific protocols. Soon OpenSSL will only support auto-negotiation (formerly known as PROTOCOL_SSLv23). My patch #26470 added PROTOCOL_TLS as alias for PROTOCOL_SSLv23. If the last idea is accepted I will remove PROTOCOL_TLS again. It hasn't been released yet. Instead I'm going to add PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER (see https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_new.html TLS_server_method(), TLS_client_method()). PROTOCOL_TLS_CLIENT is like PROTOCOL_SSLv23 but only supports client-side sockets and PROTOCOL_TLS_SERVER just server-side sockets. In my experience we can't have a SSLContext with sensible and secure settings for client and server at the same time. Hostname checking and cert validation is only sensible for client-side sockets.

Starting in 3.8 (or 3.7?) there will be only PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER.

I haven't created a ticket yet, code is at https://github.com/tiran/cpython/commits/feature/openssl_client_server


How will my proposals change TLS/SSL code?

Application must create a SSLContext object. Applications are recommended to keep the context around to benefit from session reusage and reduce overload of cert parsing.

Client side, ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT):

I don't load any certs because it is not possible to remove a cert or X509 lookup once it is loaded. create_default_context() just have to load the certs and set more secure ciper suites.

Server side, ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_PROTOCOL):

I hope this mail makes sense. Christian



More information about the Python-Dev mailing list