Issue #16037: HTTPMessage.readheaders() raises an HTTPException when more than

100 headers are read.  Adapted from patch by Jyrki Pulliainen.
This commit is contained in:
Georg Brandl 2013-10-27 07:34:48 +01:00
parent 28e78414f9
commit bf3f8eb960
4 changed files with 17 additions and 1 deletions

View File

@ -169,8 +169,8 @@ The following exceptions are raised as appropriate:
A subclass of :exc:`HTTPException`. Raised if a server responds with a HTTP A subclass of :exc:`HTTPException`. Raised if a server responds with a HTTP
status code that we don't understand. status code that we don't understand.
The constants defined in this module are:
The constants defined in this module are:
.. data:: HTTP_PORT .. data:: HTTP_PORT

View File

@ -214,6 +214,8 @@ MAXAMOUNT = 1048576
# maximal line length when calling readline(). # maximal line length when calling readline().
_MAXLINE = 65536 _MAXLINE = 65536
_MAXHEADERS = 100
class HTTPMessage(email.message.Message): class HTTPMessage(email.message.Message):
# XXX The only usage of this method is in # XXX The only usage of this method is in
@ -261,6 +263,8 @@ def parse_headers(fp, _class=HTTPMessage):
if len(line) > _MAXLINE: if len(line) > _MAXLINE:
raise LineTooLong("header line") raise LineTooLong("header line")
headers.append(line) headers.append(line)
if len(headers) > _MAXHEADERS:
raise HTTPException("got more than %d headers" % _MAXHEADERS)
if line in (b'\r\n', b'\n', b''): if line in (b'\r\n', b'\n', b''):
break break
hstring = b''.join(headers).decode('iso-8859-1') hstring = b''.join(headers).decode('iso-8859-1')

View File

@ -345,6 +345,15 @@ class BasicTest(TestCase):
self.fail("Did not expect response from HEAD request") self.fail("Did not expect response from HEAD request")
self.assertEqual(bytes(b), b'\x00'*5) self.assertEqual(bytes(b), b'\x00'*5)
def test_too_many_headers(self):
headers = '\r\n'.join('Header%d: foo' % i
for i in range(client._MAXHEADERS + 1)) + '\r\n'
text = ('HTTP/1.1 200 OK\r\n' + headers)
s = FakeSocket(text)
r = client.HTTPResponse(s)
self.assertRaisesRegex(client.HTTPException,
r"got more than \d+ headers", r.begin)
def test_send_file(self): def test_send_file(self):
expected = (b'GET /foo HTTP/1.1\r\nHost: example.com\r\n' expected = (b'GET /foo HTTP/1.1\r\nHost: example.com\r\n'
b'Accept-Encoding: identity\r\nContent-Length:') b'Accept-Encoding: identity\r\nContent-Length:')

View File

@ -81,6 +81,9 @@ Core and Builtins
Library Library
------- -------
- Issue #16037: HTTPMessage.readheaders() raises an HTTPException when more than
100 headers are read. Adapted from patch by Jyrki Pulliainen.
- Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to - Issue #16040: CVE-2013-1752: nntplib: Limit maximum line lengths to 2048 to
prevent readline() calls from consuming too much memory. Patch by Jyrki prevent readline() calls from consuming too much memory. Patch by Jyrki
Pulliainen. Pulliainen.