classification
Title: ssl module in 2.7 should provide a way to configure default context options
Type: security Stage: resolved
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: alex, benjamin.peterson, christian.heimes, dstufft, lemburg, r.david.murray, zach.ware
Priority: normal Keywords:

Created on 2014-11-13 18:59 by lemburg, last changed 2020-04-27 05:03 by zach.ware. This issue is now closed.

Messages (16)
msg231133 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-11-13 18:59
With the backport of the Python 3 ssl module, the default context options of the ssl module were changed.

While this provides better security in many cases, it also causes breakage with servers or clients which do not support TLSv1 and later.

The ssl module should provide a way to globally set the default context options to work around this to allow e.g. removing the OP_NO_SSLv3 option in order to get things to work again without having to change the application using the ssl module.
msg231134 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-11-13 19:09
As I recall it, this was discussed extensively on the python-dev mailing list.  Ideally someone should summarize that discussion here.
msg231136 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2014-11-13 21:03
Per http://legacy.python.org/dev/peps/pep-0476/#opting-out the only way to do these things is horrednously ugly because it's hardly (if ever) a good idea.
msg231138 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-11-13 21:55
On 13.11.2014 22:03, Benjamin Peterson wrote:
> 
> Benjamin Peterson added the comment:
> 
> Per http://legacy.python.org/dev/peps/pep-0476/#opting-out the only way to do these things is horrednously ugly because it's hardly (if ever) a good idea.

The point here is not about verification, it's about being able
to allow SSLv3 connections again, which the 2.7.9 version of the
ssl module disallows completely.

There are plenty devices and applications out there which don't
talk TLS and we're cutting these off without a good way to
re-enable Python 2.7 applications talk to these again.

The problem here is that Python 2's ssl module has never had a
way to access the SSL context directly, so the only way to work
around security risks of e.g. using SSLv2 for connections was
to either use SSLv3 (only) or TLSv1 (only).

This is due to the fact that OpenSSL doesn't allow you to specify
SSLv3 and later. You have to pin down the version or set up
a range that starts at SSLv2 and then disable protocols using
context options (which Python 2 has so far never exposed).

More conservative Python applications will have chosen SSLv3 as
a way to disable the broken SSLv2 support. I know that we did
in one of our applications.

Fortunately, the _ssl module itself doesn't have OP_NO_SSLv3
enabled per default, so custom protocol implementations are
probably not affected. Only the stdlib uses of SSL are.
msg231143 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2014-11-14 00:29
But you can reenable SSLv3 by alerting the context and monkeypatching as described in the PEP.
msg231145 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-11-14 01:02
On 14.11.2014 01:29, Benjamin Peterson wrote:
> 
> But you can reenable SSLv3 by alerting the context and monkeypatching as described in the PEP.

Well, I can monkeypatch the ssl module of course, but that's
not really the point here. I'm not talking about whether I can fix this
for myself or not.

The point here is that PEP 476 only addresses certificate validation, not
disabling of SSLv3 support.

AFAIK, there has been no discussion about this removal on python-dev or
in a PEP. The only place I found some discussion was on
http://bugs.python.org/issue22638, but that's targeting Python 3.5, not
a patch level release of Python or existing software.

Also note that all of the browsers mentioned in that ticket discussion
only disable the feature, but keep an option to reenable it. As it
stands, there's no simple option to do this for the ssl default
context short of monkeypatching ssl.OP_NO_SSLv3 = 0.

It would be better to add e.g. a global to the ssl module, so that
you can override the default context options easily and without
having to monkeypatch anything:

ssl.py:
DEFAULT_CONTEXT_OPTIONS = OP_NO_SSLv2 | OP_NO_SSLv3 | ...

myapp.py:
import ssl
# Reenable SSLv3 for myapp:
ssl.DEFAULT_CONTEXT_OPTIONS = ssl.DEFAULT_CONTEXT_OPTIONS & ~ssl.OP_NO_SSLv3
msg231146 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-11-14 01:19
Hmm, since neither create_default_context() nor _create_stdlib_context() are used by any other stdlib modules, I guess the removal of SSLv3 doesn't really make much difference for existing Python 2.7 applications.

I was irritated by the function names implying that they are actually used in the Python 2.7 stdlib, which is not the case.

If they ever get used, having a way to change their defaults would be a good idea, though.
msg232483 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-12-11 19:03
Reopening the ticket, since I apparently missed the two important uses in the Python 2.7.9 stdlib:

urllib2.py:
--         context = ssl._create_stdlib_context(cert_reqs=ssl.CERT_REQUIRED,

httplib.py:
--                 context = ssl._create_default_https_context()

So it turns out that the context functions are indeed used for all stdlib HTTP interfacing.

The ssl module itself doesn't use the hardcoded defaults (which is good), but having to write your own context function and then monkey patching this into the stdlib doesn't sound like a good solution to changing the default SSL context options, should this be needed.
msg232484 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2014-12-11 19:42
Usually you can pass your own context.
msg232486 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-12-11 20:24
On 11.12.2014 20:42, Benjamin Peterson wrote:
> 
> Usually you can pass your own context.

Yes, in new code, but not in existing Python 2.7 code that wasn't
written for the newly added SSL context feature.

BTW: Having a way to change the SSL options globally would be useful
for Python 3.x as well, since OpenSSL often adds new options and
it's not unlikely we'll see an OP_NO_TLSv1 option soon, given its
age and similarity to SSLv3...
https://www.imperialviolet.org/2014/12/08/poodleagain.html
(the poodle strikes back ;-))
msg232487 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2014-12-11 20:26
On Thu, Dec 11, 2014, at 15:24, Marc-Andre Lemburg wrote:
> 
> Marc-Andre Lemburg added the comment:
> 
> On 11.12.2014 20:42, Benjamin Peterson wrote:
> > 
> > Usually you can pass your own context.
> 
> Yes, in new code, but not in existing Python 2.7 code that wasn't
> written for the newly added SSL context feature.

How is modifying code to use a context different from modifying it to
mess around with a hypothetical ssl.DEFAULT_SSL_OPTIONS?

> 
> BTW: Having a way to change the SSL options globally would be useful
> for Python 3.x as well, since OpenSSL often adds new options and
> it's not unlikely we'll see an OP_NO_TLSv1 option soon, given its
> age and similarity to SSLv3...
> https://www.imperialviolet.org/2014/12/08/poodleagain.html
> (the poodle strikes back ;-))

That option already exists and is exposed. :)
msg232488 - (view) Author: Donald Stufft (dstufft) * (Python committer) Date: 2014-12-11 20:29
>> 
>> BTW: Having a way to change the SSL options globally would be useful
>> for Python 3.x as well, since OpenSSL often adds new options and
>> it's not unlikely we'll see an OP_NO_TLSv1 option soon, given its
>> age and similarity to SSLv3...
>> https://www.imperialviolet.org/2014/12/08/poodleagain.html
>> (the poodle strikes back ;-))
>
> That option already exists and is exposed. :)

It even has OP_NO_TLSv1_1 and OP_NO_TLSv1_2!
msg232489 - (view) Author: Marc-Andre Lemburg (lemburg) * (Python committer) Date: 2014-12-11 20:37
> Benjamin Peterson added the comment:
> 
> On Thu, Dec 11, 2014, at 15:24, Marc-Andre Lemburg wrote:
>>
>> Marc-Andre Lemburg added the comment:
>>
>> On 11.12.2014 20:42, Benjamin Peterson wrote:
>>>
>>> Usually you can pass your own context.
>>
>> Yes, in new code, but not in existing Python 2.7 code that wasn't
>> written for the newly added SSL context feature.
> 
> How is modifying code to use a context different from modifying it to
> mess around with a hypothetical ssl.DEFAULT_SSL_OPTIONS?

Hmm, isn't that obvious ?

You only have to add a single line of code to tweak the default
options rather than add context support throughout your application.

>> BTW: Having a way to change the SSL options globally would be useful
>> for Python 3.x as well, since OpenSSL often adds new options and
>> it's not unlikely we'll see an OP_NO_TLSv1 option soon, given its
>> age and similarity to SSLv3...
>> https://www.imperialviolet.org/2014/12/08/poodleagain.html
>> (the poodle strikes back ;-))
> 
> That option already exists and is exposed. :)

Right, but it's not used in the current default context.

Hard coding options in a function is not a good idea, really, esp.
not for things that change as often as cipher strings and protocol
options :-)
msg232505 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2014-12-12 00:17
People who are using SSLv3 should explicitly pass in a context. Globally enabling SSLv3 will surely be a footgun e.g for apps that talk to an outdated device then request a webpage.

I suppose wishing to globally use more secure defaults is a reasonable request. If someone writes a patch to put default context options in a global variable of the ssl module, we can look at it for 2.7.10.
msg275041 - (view) Author: Christian Heimes (christian.heimes) * (Python committer) Date: 2016-09-08 15:12
MAL, where is your patch? :)
msg367395 - (view) Author: Zachary Ware (zach.ware) * (Python committer) Date: 2020-04-27 05:03
With 2.7 now EOL, I'm closing the issue.
History
Date User Action Args
2020-04-27 05:03:26zach.waresetstatus: pending -> closed

nosy: + zach.ware
messages: + msg367395

resolution: out of date
stage: needs patch -> resolved
2016-09-08 15:12:13christian.heimessetstatus: open -> pending

nosy: + christian.heimes
messages: + msg275041

type: enhancement -> security
stage: needs patch
2014-12-12 00:17:15benjamin.petersonsettype: enhancement
messages: + msg232505
2014-12-11 20:38:00lemburgsetmessages: + msg232489
2014-12-11 20:29:58dstufftsetnosy: + dstufft
messages: + msg232488
2014-12-11 20:26:32benjamin.petersonsetmessages: + msg232487
2014-12-11 20:24:10lemburgsetmessages: + msg232486
2014-12-11 19:42:13benjamin.petersonsetmessages: + msg232484
2014-12-11 19:03:05lemburgsetstatus: closed -> open

messages: + msg232483
title: ssl module in 2.7.9 should provide a way to configure default context options -> ssl module in 2.7 should provide a way to configure default context options
2014-11-14 01:19:45lemburgsetstatus: open -> closed

messages: + msg231146
2014-11-14 01:02:58lemburgsetmessages: + msg231145
2014-11-14 00:29:14benjamin.petersonsetmessages: + msg231143
2014-11-13 21:55:50lemburgsetmessages: + msg231138
2014-11-13 21:03:35benjamin.petersonsetnosy: + alex, benjamin.peterson
messages: + msg231136
2014-11-13 19:09:25r.david.murraysetnosy: + r.david.murray
messages: + msg231134
2014-11-13 18:59:19lemburgcreate