summaryrefslogtreecommitdiffstats
path: root/Lib/urllib
diff options
context:
space:
mode:
authorJohnJamesUtley <81572567+JohnJamesUtley@users.noreply.github.com>2023-05-10 00:18:35 (GMT)
committerGitHub <noreply@github.com>2023-05-10 00:18:35 (GMT)
commit29f348e232e82938ba2165843c448c2b291504c5 (patch)
treeb197b032305a4fc6d791fd55d80cc1fbb9e46622 /Lib/urllib
parent2c863b3871c6127a80aa7229033219f1cdcc8711 (diff)
downloadcpython-29f348e232e82938ba2165843c448c2b291504c5.zip
cpython-29f348e232e82938ba2165843c448c2b291504c5.tar.gz
cpython-29f348e232e82938ba2165843c448c2b291504c5.tar.bz2
gh-103848: Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format (#103849)
* Adds checks to ensure that bracketed hosts found by urlsplit are of IPv6 or IPvFuture format --------- Co-authored-by: Gregory P. Smith <greg@krypto.org>
Diffstat (limited to 'Lib/urllib')
-rw-r--r--Lib/urllib/parse.py16
1 files changed, 15 insertions, 1 deletions
diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py
index 777b7c5..da00739 100644
--- a/Lib/urllib/parse.py
+++ b/Lib/urllib/parse.py
@@ -33,6 +33,7 @@ import math
import re
import types
import warnings
+import ipaddress
__all__ = ["urlparse", "urlunparse", "urljoin", "urldefrag",
"urlsplit", "urlunsplit", "urlencode", "parse_qs",
@@ -427,6 +428,17 @@ def _checknetloc(netloc):
raise ValueError("netloc '" + netloc + "' contains invalid " +
"characters under NFKC normalization")
+# Valid bracketed hosts are defined in
+# https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/
+def _check_bracketed_host(hostname):
+ if hostname.startswith('v'):
+ if not re.match(r"\Av[a-fA-F0-9]+\..+\Z", hostname):
+ raise ValueError(f"IPvFuture address is invalid")
+ else:
+ ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
+ if isinstance(ip, ipaddress.IPv4Address):
+ raise ValueError(f"An IPv4 address cannot be in brackets")
+
# typed=True avoids BytesWarnings being emitted during cache key
# comparison since this API supports both bytes and str input.
@functools.lru_cache(typed=True)
@@ -466,12 +478,14 @@ def urlsplit(url, scheme='', allow_fragments=True):
break
else:
scheme, url = url[:i].lower(), url[i+1:]
-
if url[:2] == '//':
netloc, url = _splitnetloc(url, 2)
if (('[' in netloc and ']' not in netloc) or
(']' in netloc and '[' not in netloc)):
raise ValueError("Invalid IPv6 URL")
+ if '[' in netloc and ']' in netloc:
+ bracketed_host = netloc.partition('[')[2].partition(']')[0]
+ _check_bracketed_host(bracketed_host)
if allow_fragments and '#' in url:
url, fragment = url.split('#', 1)
if '?' in url: