Skip to content

Commit 8c70fb4

Browse files
committed
Address CVE-2022-0391 for urlparse
1 parent 75f0a73 commit 8c70fb4

File tree

2 files changed

+38
-0
lines changed

2 files changed

+38
-0
lines changed

Lib/test/test_urlparse.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,36 @@ def test_telurl_params(self):
569569
self.assertEqual(p1.params, 'phone-context=+1-914-555')
570570

571571

572+
def test_urlsplit_remove_unsafe_bytes(self):
573+
# Remove ASCII tabs and newlines from input
574+
url = "http://www.python.org/java\nscript:\talert('msg\r\n')/#frag"
575+
p = urlparse.urlsplit(url)
576+
self.assertEqual(p.scheme, "http")
577+
self.assertEqual(p.netloc, "www.python.org")
578+
self.assertEqual(p.path, "/javascript:alert('msg')/")
579+
self.assertEqual(p.query, "")
580+
self.assertEqual(p.fragment, "frag")
581+
self.assertEqual(p.username, None)
582+
self.assertEqual(p.password, None)
583+
self.assertEqual(p.hostname, "www.python.org")
584+
self.assertEqual(p.port, None)
585+
self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/#frag")
586+
587+
# Remove ASCII tabs and newlines from input as unicode.
588+
url = u"http://www.python.org/java\nscript:\talert('msg\r\n')/#frag"
589+
p = urlparse.urlsplit(url)
590+
self.assertEqual(p.scheme, u"http")
591+
self.assertEqual(p.netloc, u"www.python.org")
592+
self.assertEqual(p.path, u"/javascript:alert('msg')/")
593+
self.assertEqual(p.query, u"")
594+
self.assertEqual(p.fragment, u"frag")
595+
self.assertEqual(p.username, None)
596+
self.assertEqual(p.password, None)
597+
self.assertEqual(p.hostname, u"www.python.org")
598+
self.assertEqual(p.port, None)
599+
self.assertEqual(p.geturl(), u"http://www.python.org/javascript:alert('msg')/#frag")
600+
601+
572602
def test_attributes_bad_port(self):
573603
"""Check handling of non-integer ports."""
574604
p = urlparse.urlsplit("http://www.example.net:foo")

Lib/urlparse.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@
6262
'0123456789'
6363
'+-.')
6464

65+
# Unsafe bytes to be removed per WHATWG spec
66+
_UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n']
67+
6568
MAX_CACHE_SIZE = 20
6669
_parse_cache = {}
6770

@@ -203,6 +206,8 @@ def urlsplit(url, scheme='', allow_fragments=True):
203206
if url[:i] == 'http': # optimize the common case
204207
scheme = url[:i].lower()
205208
url = url[i+1:]
209+
for b in _UNSAFE_URL_BYTES_TO_REMOVE:
210+
url = url.replace(b, '')
206211
if url[:2] == '//':
207212
netloc, url = _splitnetloc(url, 2)
208213
if (('[' in netloc and ']' not in netloc) or
@@ -227,6 +232,9 @@ def urlsplit(url, scheme='', allow_fragments=True):
227232
# not a port number
228233
scheme, url = url[:i].lower(), rest
229234

235+
for b in _UNSAFE_URL_BYTES_TO_REMOVE:
236+
url = url.replace(b, '')
237+
230238
if url[:2] == '//':
231239
netloc, url = _splitnetloc(url, 2)
232240
if (('[' in netloc and ']' not in netloc) or

0 commit comments

Comments
 (0)