New submission from Martin Panter:

In the SSL module, the wrap_socket() function (and corresponding SSLContext 
method) take a flag called “suppress_ragged_eofs”. It defaults to True, which 
makes me uncomfortable. The documentation says:

'''
The parameter “suppress_ragged_eofs” specifies how the SSLSocket.recv() method 
should signal unexpected EOF from the other end of the connection. If specified 
as True (the default), it returns a normal EOF (an empty bytes object) in 
response to unexpected EOF errors raised from the underlying socket; if False, 
it will raise the exceptions back to the caller.
'''

I understand the “unexpected EOF error” happens when the underlying socket 
indicates EOF, but the connection was not shut down at the SSL protocol level. 
As well as EOF from the other end of the connection, it can happen due to a 
proxy, or anything else on the network that can affect the connection. I think 
it may be better report this error by default, just like other unsecured 
network-level errors like connection reset or timeout. Otherwise it is too easy 
to treat this insecure EOF condition as if it were a secure EOF signal of the 
remote peer.

The flag was added as part of r64578, for Issue 1223, in Python 2.6. The reason 
given in that bug report was to help Python work with a HTTP server. However my 
theory is the server was closing the connection wrongly; if so, the server 
should have been fixed, rather than Python.

There is plenty of precedence for using suppress_ragged_eofs=True with HTTPS 
servers. As well as Issue 1223, there is Issue 494762 and Issue 500311. And in 
my experiments, Curl and Firefox both seem to treat the error the same as a 
secure EOF. Maybe there should be a way to keep supporting HTTPS servers that 
trigger the error (though I would rather not by default).

Attached is a HTTP proxy server that will let you break a connection after 
returning a set number of bytes (or any time by killing the server), which can 
trigger the error condition.

Example output of proxy server:
$ python truncating_proxy.py --limit 12345
Proxy server at http://127.0.0.1:46687
Proxying connection to www.python.org:443
Forwarded 12345 B to client

Python 2’s httplib module does not treat a short HTTP response as an error, so 
the following request gets truncated without much indication of a problem:
$ https_proxy=http://127.0.0.1:46687 python2 -c 'import urllib2; 
print(urllib2.urlopen("https://www.python.org/";).read())'
<!doctype html>
[. . .]
        <!--[if lt IE 8]>
        <div id="oldie-warning" class

----------
components: Library (Lib)
files: truncating_proxy.py
messages: 273208
nosy: martin.panter
priority: normal
severity: normal
status: open
title: Make SSL suppress_ragged_eofs default more secure
type: security
versions: Python 3.6
Added file: http://bugs.python.org/file44169/truncating_proxy.py

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue27815>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to