summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/python/python/CVE-2016-5699.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/python/python/CVE-2016-5699.patch')
-rw-r--r--meta/recipes-devtools/python/python/CVE-2016-5699.patch162
1 files changed, 162 insertions, 0 deletions
diff --git a/meta/recipes-devtools/python/python/CVE-2016-5699.patch b/meta/recipes-devtools/python/python/CVE-2016-5699.patch
new file mode 100644
index 0000000000..6eba5351d0
--- /dev/null
+++ b/meta/recipes-devtools/python/python/CVE-2016-5699.patch
@@ -0,0 +1,162 @@
1
2# HG changeset patch
3# User Serhiy Storchaka <storchaka@gmail.com>
4# Date 1426151571 -7200
5# Node ID 1c45047c51020d46246385949d5c02e026d47320
6# Parent 36bd5add973285cce9d3ec7e068bbb20c9080565
7Issue #22928: Disabled HTTP header injections in httplib.
8Original patch by Demian Brecht.
9
10Index: Python-2.7.9/Lib/httplib.py
11===================================================================
12--- Python-2.7.9.orig/Lib/httplib.py
13+++ Python-2.7.9/Lib/httplib.py
14@@ -68,6 +68,7 @@ Req-sent-unread-response _CS_REQ_S
15
16 from array import array
17 import os
18+import re
19 import socket
20 from sys import py3kwarning
21 from urlparse import urlsplit
22@@ -218,6 +219,34 @@ _MAXLINE = 65536
23 # maximum amount of headers accepted
24 _MAXHEADERS = 100
25
26+# Header name/value ABNF (http://tools.ietf.org/html/rfc7230#section-3.2)
27+#
28+# VCHAR = %x21-7E
29+# obs-text = %x80-FF
30+# header-field = field-name ":" OWS field-value OWS
31+# field-name = token
32+# field-value = *( field-content / obs-fold )
33+# field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
34+# field-vchar = VCHAR / obs-text
35+#
36+# obs-fold = CRLF 1*( SP / HTAB )
37+# ; obsolete line folding
38+# ; see Section 3.2.4
39+
40+# token = 1*tchar
41+#
42+# tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
43+# / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
44+# / DIGIT / ALPHA
45+# ; any VCHAR, except delimiters
46+#
47+# VCHAR defined in http://tools.ietf.org/html/rfc5234#appendix-B.1
48+
49+# the patterns for both name and value are more leniant than RFC
50+# definitions to allow for backwards compatibility
51+_is_legal_header_name = re.compile(r'\A[^:\s][^:\r\n]*\Z').match
52+_is_illegal_header_value = re.compile(r'\n(?![ \t])|\r(?![ \t\n])').search
53+
54
55 class HTTPMessage(mimetools.Message):
56
57@@ -978,7 +1007,16 @@ class HTTPConnection:
58 if self.__state != _CS_REQ_STARTED:
59 raise CannotSendHeader()
60
61- hdr = '%s: %s' % (header, '\r\n\t'.join([str(v) for v in values]))
62+ header = '%s' % header
63+ if not _is_legal_header_name(header):
64+ raise ValueError('Invalid header name %r' % (header,))
65+
66+ values = [str(v) for v in values]
67+ for one_value in values:
68+ if _is_illegal_header_value(one_value):
69+ raise ValueError('Invalid header value %r' % (one_value,))
70+
71+ hdr = '%s: %s' % (header, '\r\n\t'.join(values))
72 self._output(hdr)
73
74 def endheaders(self, message_body=None):
75Index: Python-2.7.9/Lib/test/test_httplib.py
76===================================================================
77--- Python-2.7.9.orig/Lib/test/test_httplib.py
78+++ Python-2.7.9/Lib/test/test_httplib.py
79@@ -138,6 +138,33 @@ class HeaderTests(TestCase):
80 conn.putheader('Content-length',42)
81 self.assertIn('Content-length: 42', conn._buffer)
82
83+ conn.putheader('Foo', ' bar ')
84+ self.assertIn(b'Foo: bar ', conn._buffer)
85+ conn.putheader('Bar', '\tbaz\t')
86+ self.assertIn(b'Bar: \tbaz\t', conn._buffer)
87+ conn.putheader('Authorization', 'Bearer mytoken')
88+ self.assertIn(b'Authorization: Bearer mytoken', conn._buffer)
89+ conn.putheader('IterHeader', 'IterA', 'IterB')
90+ self.assertIn(b'IterHeader: IterA\r\n\tIterB', conn._buffer)
91+ conn.putheader('LatinHeader', b'\xFF')
92+ self.assertIn(b'LatinHeader: \xFF', conn._buffer)
93+ conn.putheader('Utf8Header', b'\xc3\x80')
94+ self.assertIn(b'Utf8Header: \xc3\x80', conn._buffer)
95+ conn.putheader('C1-Control', b'next\x85line')
96+ self.assertIn(b'C1-Control: next\x85line', conn._buffer)
97+ conn.putheader('Embedded-Fold-Space', 'is\r\n allowed')
98+ self.assertIn(b'Embedded-Fold-Space: is\r\n allowed', conn._buffer)
99+ conn.putheader('Embedded-Fold-Tab', 'is\r\n\tallowed')
100+ self.assertIn(b'Embedded-Fold-Tab: is\r\n\tallowed', conn._buffer)
101+ conn.putheader('Key Space', 'value')
102+ self.assertIn(b'Key Space: value', conn._buffer)
103+ conn.putheader('KeySpace ', 'value')
104+ self.assertIn(b'KeySpace : value', conn._buffer)
105+ conn.putheader(b'Nonbreak\xa0Space', 'value')
106+ self.assertIn(b'Nonbreak\xa0Space: value', conn._buffer)
107+ conn.putheader(b'\xa0NonbreakSpace', 'value')
108+ self.assertIn(b'\xa0NonbreakSpace: value', conn._buffer)
109+
110 def test_ipv6host_header(self):
111 # Default host header on IPv6 transaction should wrapped by [] if
112 # its actual IPv6 address
113@@ -157,6 +184,35 @@ class HeaderTests(TestCase):
114 conn.request('GET', '/foo')
115 self.assertTrue(sock.data.startswith(expected))
116
117+ def test_invalid_headers(self):
118+ conn = httplib.HTTPConnection('example.com')
119+ conn.sock = FakeSocket('')
120+ conn.putrequest('GET', '/')
121+
122+ # http://tools.ietf.org/html/rfc7230#section-3.2.4, whitespace is no
123+ # longer allowed in header names
124+ cases = (
125+ (b'Invalid\r\nName', b'ValidValue'),
126+ (b'Invalid\rName', b'ValidValue'),
127+ (b'Invalid\nName', b'ValidValue'),
128+ (b'\r\nInvalidName', b'ValidValue'),
129+ (b'\rInvalidName', b'ValidValue'),
130+ (b'\nInvalidName', b'ValidValue'),
131+ (b' InvalidName', b'ValidValue'),
132+ (b'\tInvalidName', b'ValidValue'),
133+ (b'Invalid:Name', b'ValidValue'),
134+ (b':InvalidName', b'ValidValue'),
135+ (b'ValidName', b'Invalid\r\nValue'),
136+ (b'ValidName', b'Invalid\rValue'),
137+ (b'ValidName', b'Invalid\nValue'),
138+ (b'ValidName', b'InvalidValue\r\n'),
139+ (b'ValidName', b'InvalidValue\r'),
140+ (b'ValidName', b'InvalidValue\n'),
141+ )
142+ for name, value in cases:
143+ with self.assertRaisesRegexp(ValueError, 'Invalid header'):
144+ conn.putheader(name, value)
145+
146
147 class BasicTest(TestCase):
148 def test_status_lines(self):
149Index: Python-2.7.9/Misc/NEWS
150===================================================================
151--- Python-2.7.9.orig/Misc/NEWS
152+++ Python-2.7.9/Misc/NEWS
153@@ -13,6 +13,9 @@ What's New in Python 2.7.9?
154 Library
155 -------
156
157+- Issue #22928: Disabled HTTP header injections in httplib.
158+ Original patch by Demian Brecht.
159+
160 - Issue #22959: Remove the *check_hostname* parameter of
161 httplib.HTTPSConnection. The *context* parameter should be used instead.
162