summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnuj Mittal <anuj.mittal@intel.com>2019-10-01 22:58:17 +0300
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-10-08 22:51:35 +0100
commiteacd4b0f0ca3aa04dab5f2efd7567d4fa0c2845b (patch)
tree19bd96ac6cd968e7ed20200de3a8a54f60c75f8d
parentd1a785686f30838d6ff2702a557d996f6cecfbc0 (diff)
downloadpoky-eacd4b0f0ca3aa04dab5f2efd7567d4fa0c2845b.tar.gz
python3: upgrade 3.7.3 -> 3.7.4
Also fixes CVE-2019-9740, CVE-2019-9948. For details, see: https://docs.python.org/3.7/whatsnew/changelog.html#python-3-7-4-final (From OE-Core rev: 6b7604c536a7a2da99490a7550f997a8e35ca043) Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org> [ Backported patch removed. ] Signed-off-by: Adrian Bunk <bunk@stusta.de> [Bug fix only update] Signed-off-by: Armin Kuster <akuster808@gmail.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
-rw-r--r--meta/recipes-devtools/python/python3/CVE-2019-9740.patch151
-rw-r--r--meta/recipes-devtools/python/python3_3.7.4.bb (renamed from meta/recipes-devtools/python/python3_3.7.3.bb)5
2 files changed, 2 insertions, 154 deletions
diff --git a/meta/recipes-devtools/python/python3/CVE-2019-9740.patch b/meta/recipes-devtools/python/python3/CVE-2019-9740.patch
deleted file mode 100644
index 9bb336d7e4..0000000000
--- a/meta/recipes-devtools/python/python3/CVE-2019-9740.patch
+++ /dev/null
@@ -1,151 +0,0 @@
1From 7e200e0763f5b71c199aaf98bd5588f291585619 Mon Sep 17 00:00:00 2001
2From: =?UTF-8?q?Miro=20Hron=C4=8Dok?= <miro@hroncok.cz>
3Date: Tue, 7 May 2019 17:28:47 +0200
4Subject: [PATCH] bpo-30458: Disallow control chars in http URLs. (GH-12755)
5 (GH-13154)
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Disallow control chars in http URLs in urllib.urlopen. This addresses a potential security problem for applications that do not sanity check their URLs where http request headers could be injected.
11
12Disable https related urllib tests on a build without ssl (GH-13032)
13These tests require an SSL enabled build. Skip these tests when python is built without SSL to fix test failures.
14
15Use http.client.InvalidURL instead of ValueError as the new error case's exception. (GH-13044)
16
17Backport Co-Authored-By: Miro HronĨok <miro@hroncok.cz>
18Upstream-Status: Backport[https://github.com/python/cpython/commit/7e200e0763f5b71c199aaf98bd5588f291585619]
19CVE: CVE-2019-9740
20CVE: CVE-2019-9947
21Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
22---
23 Lib/http/client.py | 15 ++++++
24 Lib/test/test_urllib.py | 53 +++++++++++++++++++
25 Lib/test/test_xmlrpc.py | 7 ++-
26 .../2019-04-10-08-53-30.bpo-30458.51E-DA.rst | 1 +
27 4 files changed, 75 insertions(+), 1 deletion(-)
28 create mode 100644 Misc/NEWS.d/next/Security/2019-04-10-08-53-30.bpo-30458.51E-DA.rst
29
30diff --git a/Lib/http/client.py b/Lib/http/client.py
31index 1de151c38e92..2afd452fe30f 100644
32--- a/Lib/http/client.py
33+++ b/Lib/http/client.py
34@@ -140,6 +140,16 @@
35 _is_legal_header_name = re.compile(rb'[^:\s][^:\r\n]*').fullmatch
36 _is_illegal_header_value = re.compile(rb'\n(?![ \t])|\r(?![ \t\n])').search
37
38+# These characters are not allowed within HTTP URL paths.
39+# See https://tools.ietf.org/html/rfc3986#section-3.3 and the
40+# https://tools.ietf.org/html/rfc3986#appendix-A pchar definition.
41+# Prevents CVE-2019-9740. Includes control characters such as \r\n.
42+# We don't restrict chars above \x7f as putrequest() limits us to ASCII.
43+_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]')
44+# Arguably only these _should_ allowed:
45+# _is_allowed_url_pchars_re = re.compile(r"^[/!$&'()*+,;=:@%a-zA-Z0-9._~-]+$")
46+# We are more lenient for assumed real world compatibility purposes.
47+
48 # We always set the Content-Length header for these methods because some
49 # servers will otherwise respond with a 411
50 _METHODS_EXPECTING_BODY = {'PATCH', 'POST', 'PUT'}
51@@ -1101,6 +1111,11 @@ def putrequest(self, method, url, skip_host=False,
52 self._method = method
53 if not url:
54 url = '/'
55+ # Prevent CVE-2019-9740.
56+ match = _contains_disallowed_url_pchar_re.search(url)
57+ if match:
58+ raise InvalidURL(f"URL can't contain control characters. {url!r} "
59+ f"(found at least {match.group()!r})")
60 request = '%s %s %s' % (method, url, self._http_vsn_str)
61
62 # Non-ASCII characters should have been eliminated earlier
63diff --git a/Lib/test/test_urllib.py b/Lib/test/test_urllib.py
64index 2ac73b58d832..7214492eca9d 100644
65--- a/Lib/test/test_urllib.py
66+++ b/Lib/test/test_urllib.py
67@@ -329,6 +329,59 @@ def test_willclose(self):
68 finally:
69 self.unfakehttp()
70
71+ @unittest.skipUnless(ssl, "ssl module required")
72+ def test_url_with_control_char_rejected(self):
73+ for char_no in list(range(0, 0x21)) + [0x7f]:
74+ char = chr(char_no)
75+ schemeless_url = f"//localhost:7777/test{char}/"
76+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.")
77+ try:
78+ # We explicitly test urllib.request.urlopen() instead of the top
79+ # level 'def urlopen()' function defined in this... (quite ugly)
80+ # test suite. They use different url opening codepaths. Plain
81+ # urlopen uses FancyURLOpener which goes via a codepath that
82+ # calls urllib.parse.quote() on the URL which makes all of the
83+ # above attempts at injection within the url _path_ safe.
84+ escaped_char_repr = repr(char).replace('\\', r'\\')
85+ InvalidURL = http.client.InvalidURL
86+ with self.assertRaisesRegex(
87+ InvalidURL, f"contain control.*{escaped_char_repr}"):
88+ urllib.request.urlopen(f"http:{schemeless_url}")
89+ with self.assertRaisesRegex(
90+ InvalidURL, f"contain control.*{escaped_char_repr}"):
91+ urllib.request.urlopen(f"https:{schemeless_url}")
92+ # This code path quotes the URL so there is no injection.
93+ resp = urlopen(f"http:{schemeless_url}")
94+ self.assertNotIn(char, resp.geturl())
95+ finally:
96+ self.unfakehttp()
97+
98+ @unittest.skipUnless(ssl, "ssl module required")
99+ def test_url_with_newline_header_injection_rejected(self):
100+ self.fakehttp(b"HTTP/1.1 200 OK\r\n\r\nHello.")
101+ host = "localhost:7777?a=1 HTTP/1.1\r\nX-injected: header\r\nTEST: 123"
102+ schemeless_url = "//" + host + ":8080/test/?test=a"
103+ try:
104+ # We explicitly test urllib.request.urlopen() instead of the top
105+ # level 'def urlopen()' function defined in this... (quite ugly)
106+ # test suite. They use different url opening codepaths. Plain
107+ # urlopen uses FancyURLOpener which goes via a codepath that
108+ # calls urllib.parse.quote() on the URL which makes all of the
109+ # above attempts at injection within the url _path_ safe.
110+ InvalidURL = http.client.InvalidURL
111+ with self.assertRaisesRegex(
112+ InvalidURL, r"contain control.*\\r.*(found at least . .)"):
113+ urllib.request.urlopen(f"http:{schemeless_url}")
114+ with self.assertRaisesRegex(InvalidURL, r"contain control.*\\n"):
115+ urllib.request.urlopen(f"https:{schemeless_url}")
116+ # This code path quotes the URL so there is no injection.
117+ resp = urlopen(f"http:{schemeless_url}")
118+ self.assertNotIn(' ', resp.geturl())
119+ self.assertNotIn('\r', resp.geturl())
120+ self.assertNotIn('\n', resp.geturl())
121+ finally:
122+ self.unfakehttp()
123+
124 def test_read_0_9(self):
125 # "0.9" response accepted (but not "simple responses" without
126 # a status line)
127diff --git a/Lib/test/test_xmlrpc.py b/Lib/test/test_xmlrpc.py
128index 32263f7f0b3b..0e002ec4ef9f 100644
129--- a/Lib/test/test_xmlrpc.py
130+++ b/Lib/test/test_xmlrpc.py
131@@ -945,7 +945,12 @@ def test_unicode_host(self):
132 def test_partial_post(self):
133 # Check that a partial POST doesn't make the server loop: issue #14001.
134 conn = http.client.HTTPConnection(ADDR, PORT)
135- conn.request('POST', '/RPC2 HTTP/1.0\r\nContent-Length: 100\r\n\r\nbye')
136+ conn.send('POST /RPC2 HTTP/1.0\r\n'
137+ 'Content-Length: 100\r\n\r\n'
138+ 'bye HTTP/1.1\r\n'
139+ f'Host: {ADDR}:{PORT}\r\n'
140+ 'Accept-Encoding: identity\r\n'
141+ 'Content-Length: 0\r\n\r\n'.encode('ascii'))
142 conn.close()
143
144 def test_context_manager(self):
145diff --git a/Misc/NEWS.d/next/Security/2019-04-10-08-53-30.bpo-30458.51E-DA.rst b/Misc/NEWS.d/next/Security/2019-04-10-08-53-30.bpo-30458.51E-DA.rst
146new file mode 100644
147index 000000000000..ed8027fb4d64
148--- /dev/null
149+++ b/Misc/NEWS.d/next/Security/2019-04-10-08-53-30.bpo-30458.51E-DA.rst
150@@ -0,0 +1 @@
151+Address CVE-2019-9740 by disallowing URL paths with embedded whitespace or control characters through into the underlying http client request. Such potentially malicious header injection URLs now cause an http.client.InvalidURL exception to be raised.
diff --git a/meta/recipes-devtools/python/python3_3.7.3.bb b/meta/recipes-devtools/python/python3_3.7.4.bb
index 1f1441f4ac..dd163512bb 100644
--- a/meta/recipes-devtools/python/python3_3.7.3.bb
+++ b/meta/recipes-devtools/python/python3_3.7.4.bb
@@ -22,7 +22,6 @@ SRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
22 file://0002-Don-t-do-runtime-test-to-get-float-byte-order.patch \ 22 file://0002-Don-t-do-runtime-test-to-get-float-byte-order.patch \
23 file://0003-setup.py-pass-missing-libraries-to-Extension-for-mul.patch \ 23 file://0003-setup.py-pass-missing-libraries-to-Extension-for-mul.patch \
24 file://0001-Lib-sysconfig.py-fix-another-place-where-lib-is-hard.patch \ 24 file://0001-Lib-sysconfig.py-fix-another-place-where-lib-is-hard.patch \
25 file://CVE-2019-9740.patch \
26 " 25 "
27 26
28SRC_URI_append_class-native = " \ 27SRC_URI_append_class-native = " \
@@ -33,8 +32,8 @@ SRC_URI_append_class-nativesdk = " \
33 file://0001-main.c-if-OEPYTHON3HOME-is-set-use-instead-of-PYTHON.patch \ 32 file://0001-main.c-if-OEPYTHON3HOME-is-set-use-instead-of-PYTHON.patch \
34 " 33 "
35 34
36SRC_URI[md5sum] = "93df27aec0cd18d6d42173e601ffbbfd" 35SRC_URI[md5sum] = "d33e4aae66097051c2eca45ee3604803"
37SRC_URI[sha256sum] = "da60b54064d4cfcd9c26576f6df2690e62085123826cff2e667e72a91952d318" 36SRC_URI[sha256sum] = "fb799134b868199930b75f26678f18932214042639cd52b16da7fd134cd9b13f"
38 37
39# exclude pre-releases for both python 2.x and 3.x 38# exclude pre-releases for both python 2.x and 3.x
40UPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>\d+(\.\d+)+).tar" 39UPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>\d+(\.\d+)+).tar"