mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed CVE-2025-27556 -- Mitigated potential DoS in url_has_allowed_host_and_scheme() on Windows.
Thank you sw0rd1ight for the report.
This commit is contained in:
		| @@ -6,6 +6,7 @@ from urllib.parse import urlsplit | ||||
|  | ||||
| from django.core.exceptions import ValidationError | ||||
| from django.utils.deconstruct import deconstructible | ||||
| from django.utils.http import MAX_URL_LENGTH | ||||
| from django.utils.ipv6 import is_valid_ipv6_address | ||||
| from django.utils.regex_helper import _lazy_re_compile | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| @@ -152,7 +153,7 @@ class URLValidator(RegexValidator): | ||||
|     message = _("Enter a valid URL.") | ||||
|     schemes = ["http", "https", "ftp", "ftps"] | ||||
|     unsafe_chars = frozenset("\t\r\n") | ||||
|     max_length = 2048 | ||||
|     max_length = MAX_URL_LENGTH | ||||
|  | ||||
|     def __init__(self, schemes=None, **kwargs): | ||||
|         super().__init__(**kwargs) | ||||
|   | ||||
| @@ -13,7 +13,7 @@ from django.core.exceptions import SuspiciousOperation, ValidationError | ||||
| from django.core.validators import EmailValidator | ||||
| from django.utils.deprecation import RemovedInDjango70Warning | ||||
| from django.utils.functional import Promise, cached_property, keep_lazy, keep_lazy_text | ||||
| from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS | ||||
| from django.utils.http import MAX_URL_LENGTH, RFC3986_GENDELIMS, RFC3986_SUBDELIMS | ||||
| from django.utils.regex_helper import _lazy_re_compile | ||||
| from django.utils.safestring import SafeData, SafeString, mark_safe | ||||
| from django.utils.text import normalize_newlines | ||||
| @@ -41,7 +41,6 @@ VOID_ELEMENTS = frozenset( | ||||
|     ) | ||||
| ) | ||||
|  | ||||
| MAX_URL_LENGTH = 2048 | ||||
| MAX_STRIP_TAGS_DEPTH = 50 | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,7 @@ ASCTIME_DATE = _lazy_re_compile(r"^\w{3} %s %s %s %s$" % (__M, __D2, __T, __Y)) | ||||
|  | ||||
| RFC3986_GENDELIMS = ":/?#[]@" | ||||
| RFC3986_SUBDELIMS = "!$&'()*+,;=" | ||||
| MAX_URL_LENGTH = 2048 | ||||
|  | ||||
|  | ||||
| def urlencode(query, doseq=False): | ||||
| @@ -274,7 +275,10 @@ def url_has_allowed_host_and_scheme(url, allowed_hosts, require_https=False): | ||||
| def _url_has_allowed_host_and_scheme(url, allowed_hosts, require_https=False): | ||||
|     # Chrome considers any URL with more than two slashes to be absolute, but | ||||
|     # urlsplit is not so flexible. Treat any url with three slashes as unsafe. | ||||
|     if url.startswith("///"): | ||||
|     if url.startswith("///") or len(url) > MAX_URL_LENGTH: | ||||
|         # urlsplit does not perform validation of inputs. Unicode normalization | ||||
|         # is very slow on Windows and can be a DoS attack vector. | ||||
|         # https://docs.python.org/3/library/urllib.parse.html#url-parsing-security | ||||
|         return False | ||||
|     try: | ||||
|         url_info = urlsplit(url) | ||||
|   | ||||
| @@ -5,3 +5,13 @@ Django 5.0.14 release notes | ||||
| *April 2, 2025* | ||||
|  | ||||
| Django 5.0.14 fixes a security issue with severity "moderate" in 5.0.13. | ||||
|  | ||||
| CVE-2025-27556: Potential denial-of-service vulnerability in ``LoginView``, ``LogoutView``, and ``set_language()`` on Windows | ||||
| ============================================================================================================================= | ||||
|  | ||||
| Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on | ||||
| Windows. As a consequence, :class:`~django.contrib.auth.views.LoginView`, | ||||
| :class:`~django.contrib.auth.views.LogoutView`, and | ||||
| :func:`~django.views.i18n.set_language` were subject to a potential | ||||
| denial-of-service attack via certain inputs with a very large number of Unicode | ||||
| characters. | ||||
|   | ||||
| @@ -7,6 +7,16 @@ Django 5.1.8 release notes | ||||
| Django 5.1.8 fixes a security issue with severity "moderate" and several bugs | ||||
| in 5.1.7. | ||||
|  | ||||
| CVE-2025-27556: Potential denial-of-service vulnerability in ``LoginView``, ``LogoutView``, and ``set_language()`` on Windows | ||||
| ============================================================================================================================= | ||||
|  | ||||
| Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on | ||||
| Windows. As a consequence, :class:`~django.contrib.auth.views.LoginView`, | ||||
| :class:`~django.contrib.auth.views.LogoutView`, and | ||||
| :func:`~django.views.i18n.set_language` were subject to a potential | ||||
| denial-of-service attack via certain inputs with a very large number of Unicode | ||||
| characters. | ||||
|  | ||||
| Bugfixes | ||||
| ======== | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ from django.test import SimpleTestCase | ||||
| from django.utils.datastructures import MultiValueDict | ||||
| from django.utils.http import ( | ||||
|     MAX_HEADER_LENGTH, | ||||
|     MAX_URL_LENGTH, | ||||
|     base36_to_int, | ||||
|     content_disposition_header, | ||||
|     escape_leading_slashes, | ||||
| @@ -274,6 +275,21 @@ class URLHasAllowedHostAndSchemeTests(unittest.TestCase): | ||||
|                     False, | ||||
|                 ) | ||||
|  | ||||
|     def test_max_url_length(self): | ||||
|         allowed_host = "example.com" | ||||
|         max_extra_characters = "é" * (MAX_URL_LENGTH - len(allowed_host) - 1) | ||||
|         max_length_boundary_url = f"{allowed_host}/{max_extra_characters}" | ||||
|         cases = [ | ||||
|             (max_length_boundary_url, True), | ||||
|             (max_length_boundary_url + "ú", False), | ||||
|         ] | ||||
|         for url, expected in cases: | ||||
|             with self.subTest(url=url): | ||||
|                 self.assertIs( | ||||
|                     url_has_allowed_host_and_scheme(url, allowed_hosts={allowed_host}), | ||||
|                     expected, | ||||
|                 ) | ||||
|  | ||||
|  | ||||
| class URLSafeBase64Tests(unittest.TestCase): | ||||
|     def test_roundtrip(self): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user