Skip to content

Commit

Permalink
Merge pull request #14 from ActiveState/cve-2022-0391
Browse files Browse the repository at this point in the history
Address CVE-2022-0391 for urlparse
  • Loading branch information
ucodery authored Jun 27, 2022
2 parents 75f0a73 + 2bff6bd commit 28b0ed3
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
34 changes: 34 additions & 0 deletions Lib/test/test_urlparse.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (C) 2022 ActiveState Software Inc.
# test_urlparse.py is licensed under the PSFLv2 License.
# See the file LICENSE for details.

from test import test_support
import sys
import unicodedata
Expand Down Expand Up @@ -569,6 +573,36 @@ def test_telurl_params(self):
self.assertEqual(p1.params, 'phone-context=+1-914-555')


def test_urlsplit_remove_unsafe_bytes(self):
# Remove ASCII tabs and newlines from input
url = "http://www.python.org/java\nscript:\talert('msg\r\n')/#frag"
p = urlparse.urlsplit(url)
self.assertEqual(p.scheme, "http")
self.assertEqual(p.netloc, "www.python.org")
self.assertEqual(p.path, "/javascript:alert('msg')/")
self.assertEqual(p.query, "")
self.assertEqual(p.fragment, "frag")
self.assertEqual(p.username, None)
self.assertEqual(p.password, None)
self.assertEqual(p.hostname, "www.python.org")
self.assertEqual(p.port, None)
self.assertEqual(p.geturl(), "http://www.python.org/javascript:alert('msg')/#frag")

# Remove ASCII tabs and newlines from input as unicode.
url = u"http://www.python.org/java\nscript:\talert('msg\r\n')/#frag"
p = urlparse.urlsplit(url)
self.assertEqual(p.scheme, u"http")
self.assertEqual(p.netloc, u"www.python.org")
self.assertEqual(p.path, u"/javascript:alert('msg')/")
self.assertEqual(p.query, u"")
self.assertEqual(p.fragment, u"frag")
self.assertEqual(p.username, None)
self.assertEqual(p.password, None)
self.assertEqual(p.hostname, u"www.python.org")
self.assertEqual(p.port, None)
self.assertEqual(p.geturl(), u"http://www.python.org/javascript:alert('msg')/#frag")


def test_attributes_bad_port(self):
"""Check handling of non-integer ports."""
p = urlparse.urlsplit("http://www.example.net:foo")
Expand Down
12 changes: 12 additions & 0 deletions Lib/urlparse.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Copyright (C) 2022 ActiveState Software Inc.
# urlparse.py is licensed under the PSFLv2 License.
# See the file LICENSE for details.

"""Parse (absolute and relative) URLs.
urlparse module is based upon the following RFC specifications.
Expand Down Expand Up @@ -62,6 +66,9 @@
'0123456789'
'+-.')

# Unsafe bytes to be removed per WHATWG spec
_UNSAFE_URL_BYTES_TO_REMOVE = ['\t', '\r', '\n']

MAX_CACHE_SIZE = 20
_parse_cache = {}

Expand Down Expand Up @@ -203,6 +210,8 @@ def urlsplit(url, scheme='', allow_fragments=True):
if url[:i] == 'http': # optimize the common case
scheme = url[:i].lower()
url = url[i+1:]
for b in _UNSAFE_URL_BYTES_TO_REMOVE:
url = url.replace(b, '')
if url[:2] == '//':
netloc, url = _splitnetloc(url, 2)
if (('[' in netloc and ']' not in netloc) or
Expand All @@ -227,6 +236,9 @@ def urlsplit(url, scheme='', allow_fragments=True):
# not a port number
scheme, url = url[:i].lower(), rest

for b in _UNSAFE_URL_BYTES_TO_REMOVE:
url = url.replace(b, '')

if url[:2] == '//':
netloc, url = _splitnetloc(url, 2)
if (('[' in netloc and ']' not in netloc) or
Expand Down
7 changes: 7 additions & 0 deletions Misc/NEWS.d/2.7.18.5.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.. bpo: 0
.. date: 2022-06-27
.. nonce: caft@D
.. release date: 2022-06-27
.. section: Library
Address CVE-2022-0391 in urlparse

0 comments on commit 28b0ed3

Please sign in to comment.