diff options
author | JohnJamesUtley <81572567+JohnJamesUtley@users.noreply.github.com> | 2023-05-10 00:18:35 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-10 00:18:35 (GMT) |
commit | 29f348e232e82938ba2165843c448c2b291504c5 (patch) | |
tree | b197b032305a4fc6d791fd55d80cc1fbb9e46622 /Lib/urllib | |
parent | 2c863b3871c6127a80aa7229033219f1cdcc8711 (diff) | |
download | cpython-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.py | 16 |
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: |