diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2024-12-01 12:31:12 +0100 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2024-12-03 09:50:11 +0100 |
| commit | f663277a4c22ef96cbdebfd0ed76155b9d37b4f8 (patch) | |
| tree | 9c87c428aca8ee8b64878a689ba38b7e1892c141 /django/utils | |
| parent | 0acff0fd1f5ad09367aacb51b2b68699c6ce7929 (diff) | |
[4.2.x] Refs CVE-2024-11168 -- Updated vendored _urlsplit() to properly validate IPv6 and IPvFuture addresses.
Refs Python CVE-2024-11168. Django should not affected, but others who
incorrectly use internal function _urlsplit() with unsanitized input
could be at risk.
https://github.com/python/cpython/pull/103849
Diffstat (limited to 'django/utils')
| -rw-r--r-- | django/utils/http.py | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/django/utils/http.py b/django/utils/http.py index 3e7acb5835..94ad60bdbc 100644 --- a/django/utils/http.py +++ b/django/utils/http.py @@ -1,5 +1,6 @@ import base64 import datetime +import ipaddress import re import unicodedata from binascii import Error as BinasciiError @@ -310,6 +311,21 @@ def _remove_unsafe_bytes_from_url(url): # TODO: Remove when dropping support for PY38. +def _check_bracketed_host(hostname): + # Valid bracketed hosts are defined in + # https://www.rfc-editor.org/rfc/rfc3986#page-49 and + # https://url.spec.whatwg.org/. + if hostname.startswith("v"): + if not re.match(r"\Av[a-fA-F0-9]+\..+\Z", hostname): + raise ValueError("IPvFuture address is invalid") + else: + # Throws Value Error if not IPv6 or IPv4. + ip = ipaddress.ip_address(hostname) + if isinstance(ip, ipaddress.IPv4Address): + raise ValueError("An IPv4 address cannot be in brackets") + + +# TODO: Remove when dropping support for PY38. # Backport of urllib.parse.urlsplit() from Python 3.9. def _urlsplit(url, scheme="", allow_fragments=True): """Parse a URL into 5 components: @@ -336,6 +352,9 @@ def _urlsplit(url, scheme="", allow_fragments=True): "]" 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: |
