diff options
Diffstat (limited to 'meta/recipes-devtools/python/python/bpo-36216-cve-2019-9636.patch')
-rw-r--r-- | meta/recipes-devtools/python/python/bpo-36216-cve-2019-9636.patch | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/meta/recipes-devtools/python/python/bpo-36216-cve-2019-9636.patch b/meta/recipes-devtools/python/python/bpo-36216-cve-2019-9636.patch new file mode 100644 index 0000000000..352b13ba9b --- /dev/null +++ b/meta/recipes-devtools/python/python/bpo-36216-cve-2019-9636.patch | |||
@@ -0,0 +1,111 @@ | |||
1 | From 3e3669c9c41a27e1466e2c28b3906e3dd0ce3e7e Mon Sep 17 00:00:00 2001 | ||
2 | From: Steve Dower <steve.dower@python.org> | ||
3 | Date: Thu, 7 Mar 2019 08:25:22 -0800 | ||
4 | Subject: [PATCH] bpo-36216: Add check for characters in netloc that normalize | ||
5 | to separators (GH-12201) | ||
6 | |||
7 | CVE: CVE-2019-9636 | ||
8 | |||
9 | Upstream-Status: Backport https://github.com/python/cpython/pull/12216/commits/3e3669c9c41a27e1466e2c28b3906e3dd0ce3e7e | ||
10 | |||
11 | Signed-off-by: Martin Jansa <Martin.Jansa@gmail.com> | ||
12 | --- | ||
13 | Doc/library/urlparse.rst | 20 ++++++++++++++++ | ||
14 | Lib/test/test_urlparse.py | 24 +++++++++++++++++++ | ||
15 | Lib/urlparse.py | 17 +++++++++++++ | ||
16 | .../2019-03-06-09-38-40.bpo-36216.6q1m4a.rst | 3 +++ | ||
17 | 4 files changed, 64 insertions(+) | ||
18 | create mode 100644 Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst | ||
19 | |||
20 | diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py | ||
21 | index 4e1ded73c266..73b0228ea8e3 100644 | ||
22 | --- a/Lib/test/test_urlparse.py | ||
23 | +++ b/Lib/test/test_urlparse.py | ||
24 | @@ -1,4 +1,6 @@ | ||
25 | from test import test_support | ||
26 | +import sys | ||
27 | +import unicodedata | ||
28 | import unittest | ||
29 | import urlparse | ||
30 | |||
31 | @@ -624,6 +626,28 @@ def test_portseparator(self): | ||
32 | self.assertEqual(urlparse.urlparse("http://www.python.org:80"), | ||
33 | ('http','www.python.org:80','','','','')) | ||
34 | |||
35 | + def test_urlsplit_normalization(self): | ||
36 | + # Certain characters should never occur in the netloc, | ||
37 | + # including under normalization. | ||
38 | + # Ensure that ALL of them are detected and cause an error | ||
39 | + illegal_chars = u'/:#?@' | ||
40 | + hex_chars = {'{:04X}'.format(ord(c)) for c in illegal_chars} | ||
41 | + denorm_chars = [ | ||
42 | + c for c in map(unichr, range(128, sys.maxunicode)) | ||
43 | + if (hex_chars & set(unicodedata.decomposition(c).split())) | ||
44 | + and c not in illegal_chars | ||
45 | + ] | ||
46 | + # Sanity check that we found at least one such character | ||
47 | + self.assertIn(u'\u2100', denorm_chars) | ||
48 | + self.assertIn(u'\uFF03', denorm_chars) | ||
49 | + | ||
50 | + for scheme in [u"http", u"https", u"ftp"]: | ||
51 | + for c in denorm_chars: | ||
52 | + url = u"{}://netloc{}false.netloc/path".format(scheme, c) | ||
53 | + print "Checking %r" % url | ||
54 | + with self.assertRaises(ValueError): | ||
55 | + urlparse.urlsplit(url) | ||
56 | + | ||
57 | def test_main(): | ||
58 | test_support.run_unittest(UrlParseTestCase) | ||
59 | |||
60 | diff --git a/Lib/urlparse.py b/Lib/urlparse.py | ||
61 | index f7c2b032b097..54eda08651ab 100644 | ||
62 | --- a/Lib/urlparse.py | ||
63 | +++ b/Lib/urlparse.py | ||
64 | @@ -165,6 +165,21 @@ def _splitnetloc(url, start=0): | ||
65 | delim = min(delim, wdelim) # use earliest delim position | ||
66 | return url[start:delim], url[delim:] # return (domain, rest) | ||
67 | |||
68 | +def _checknetloc(netloc): | ||
69 | + if not netloc or not isinstance(netloc, unicode): | ||
70 | + return | ||
71 | + # looking for characters like \u2100 that expand to 'a/c' | ||
72 | + # IDNA uses NFKC equivalence, so normalize for this check | ||
73 | + import unicodedata | ||
74 | + netloc2 = unicodedata.normalize('NFKC', netloc) | ||
75 | + if netloc == netloc2: | ||
76 | + return | ||
77 | + _, _, netloc = netloc.rpartition('@') # anything to the left of '@' is okay | ||
78 | + for c in '/?#@:': | ||
79 | + if c in netloc2: | ||
80 | + raise ValueError("netloc '" + netloc2 + "' contains invalid " + | ||
81 | + "characters under NFKC normalization") | ||
82 | + | ||
83 | def urlsplit(url, scheme='', allow_fragments=True): | ||
84 | """Parse a URL into 5 components: | ||
85 | <scheme>://<netloc>/<path>?<query>#<fragment> | ||
86 | @@ -193,6 +208,7 @@ def urlsplit(url, scheme='', allow_fragments=True): | ||
87 | url, fragment = url.split('#', 1) | ||
88 | if '?' in url: | ||
89 | url, query = url.split('?', 1) | ||
90 | + _checknetloc(netloc) | ||
91 | v = SplitResult(scheme, netloc, url, query, fragment) | ||
92 | _parse_cache[key] = v | ||
93 | return v | ||
94 | @@ -216,6 +232,7 @@ def urlsplit(url, scheme='', allow_fragments=True): | ||
95 | url, fragment = url.split('#', 1) | ||
96 | if '?' in url: | ||
97 | url, query = url.split('?', 1) | ||
98 | + _checknetloc(netloc) | ||
99 | v = SplitResult(scheme, netloc, url, query, fragment) | ||
100 | _parse_cache[key] = v | ||
101 | return v | ||
102 | diff --git a/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst b/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst | ||
103 | new file mode 100644 | ||
104 | index 000000000000..1e1ad92c6feb | ||
105 | --- /dev/null | ||
106 | +++ b/Misc/NEWS.d/next/Security/2019-03-06-09-38-40.bpo-36216.6q1m4a.rst | ||
107 | @@ -0,0 +1,3 @@ | ||
108 | +Changes urlsplit() to raise ValueError when the URL contains characters that | ||
109 | +decompose under IDNA encoding (NFKC-normalization) into characters that | ||
110 | +affect how the URL is parsed. | ||
111 | \ No newline at end of file | ||