File urllib3-disallow-control-chars-in-http-urls.patch of Package python-urllib3.17522
Stripped down Backport of:
https://github.com/urllib3/urllib3/pull/1591
(basically just this commit: https://github.com/urllib3/urllib3/pull/1591/commits/c147f359520cab339ec96b3ef96e471c0da261f6)
and
https://github.com/urllib3/urllib3/pull/1593
Index: urllib3-1.24/src/urllib3/util/url.py
===================================================================
--- urllib3-1.24.orig/src/urllib3/util/url.py
+++ urllib3-1.24/src/urllib3/util/url.py
@@ -1,7 +1,9 @@
from __future__ import absolute_import
from collections import namedtuple
+import re
from ..exceptions import LocationParseError
+from six.moves.urllib.parse import quote
url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment']
@@ -10,6 +12,8 @@ url_attrs = ['scheme', 'auth', 'host', '
# urllib3 infers URLs without a scheme (None) to be http.
NORMALIZABLE_SCHEMES = ('http', 'https', None)
+_contains_disallowed_url_pchar_re = re.compile('[\x00-\x20\x7f]')
+
class Url(namedtuple('Url', url_attrs)):
"""
@@ -155,6 +159,10 @@ def parse_url(url):
# Empty
return Url()
+ # Prevent CVE-2019-9740.
+ # adapted from https://github.com/python/cpython/pull/12755
+ url = _contains_disallowed_url_pchar_re.sub(lambda match: quote(match.group()), url)
+
scheme = None
auth = None
host = None
Index: urllib3-1.24/test/test_util.py
===================================================================
--- urllib3-1.24.orig/test/test_util.py
+++ urllib3-1.24/test/test_util.py
@@ -200,6 +200,27 @@ class TestUtil(object):
with pytest.raises(ValueError):
parse_url('[::1')
+ @pytest.mark.parametrize('url, expected_url', [
+ (
+ 'http://localhost/ HTTP/1.1\r\nHEADER: INJECTED\r\nIgnore:',
+ Url('http', host='localhost', port=None,
+ path='/%20HTTP/1.1%0D%0AHEADER:%20INJECTED%0D%0AIgnore:')
+ ),
+ (
+ u'http://localhost/ HTTP/1.1\r\nHEADER: INJECTED\r\nIgnore:',
+ Url('http', host='localhost', port=None,
+ path='/%20HTTP/1.1%0D%0AHEADER:%20INJECTED%0D%0AIgnore:')
+ ),
+ (
+ 'http://localhost/ ?q=\r\n',
+ Url('http', host='localhost', path='/%20', query='q=%0D%0A')
+ ),
+ ])
+ def test_parse_url_contains_control_characters(self, url, expected_url):
+ # see CVE-2019-9740
+ url = parse_url(url)
+ assert url == expected_url
+
def test_Url_str(self):
U = Url('http', host='google.com')
assert str(U) == U.url