Potential denial-of-service vulnerability in HttpResponseRedirect and HttpResponsePermanentRedirect on Windows
Description
An issue was discovered in 5.1 before 5.1.14, 4.2 before 4.2.26, and 5.2 before 5.2.8. NFKC normalization in Python is slow on Windows. As a consequence, django.http.HttpResponseRedirect, django.http.HttpResponsePermanentRedirect, and the shortcut django.shortcuts.redirect were subject to a potential denial-of-service attack via certain inputs with a very large number of Unicode characters. Earlier, unsupported Django series (such as 5.0.x, 4.1.x, and 3.2.x) were not evaluated and may also be affected. Django would like to thank Seokchan Yoon for reporting this issue.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
djangoPyPI | >= 5.2a1, < 5.2.8 | 5.2.8 |
djangoPyPI | >= 5.0a1, < 5.1.14 | 5.1.14 |
djangoPyPI | < 4.2.26 | 4.2.26 |
Affected products
1- Range: 5.2
Patches
43790593781d2[5.1.x] Fixed CVE-2025-64458 -- Mitigated potential DoS in HttpResponseRedirect/HttpResponsePermanentRedirect on Windows.
4 files changed · +27 −4
django/http/response.py+7 −2 modified@@ -21,7 +21,7 @@ from django.utils import timezone from django.utils.datastructures import CaseInsensitiveMapping from django.utils.encoding import iri_to_uri -from django.utils.http import content_disposition_header, http_date +from django.utils.http import MAX_URL_LENGTH, content_disposition_header, http_date from django.utils.regex_helper import _lazy_re_compile _charset_from_content_type_re = _lazy_re_compile( @@ -616,7 +616,12 @@ class HttpResponseRedirectBase(HttpResponse): def __init__(self, redirect_to, *args, **kwargs): super().__init__(*args, **kwargs) self["Location"] = iri_to_uri(redirect_to) - parsed = urlparse(str(redirect_to)) + redirect_to_str = str(redirect_to) + if len(redirect_to_str) > MAX_URL_LENGTH: + raise DisallowedRedirect( + f"Unsafe redirect exceeding {MAX_URL_LENGTH} characters" + ) + parsed = urlparse(redirect_to_str) if parsed.scheme and parsed.scheme not in self.allowed_schemes: raise DisallowedRedirect( "Unsafe redirect to URL with protocol '%s'" % parsed.scheme
docs/releases/4.2.26.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 4.2.26 release notes Django 4.2.26 fixes one security issue with severity "high" and one security issue with severity "moderate" in 4.2.25. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
docs/releases/5.1.14.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 5.1.14 release notes Django 5.1.14 fixes one security issue with severity "high" and one security issue with severity "moderate" in 5.1.13. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
tests/httpwrappers/tests.py+2 −0 modified@@ -24,6 +24,7 @@ ) from django.test import SimpleTestCase from django.utils.functional import lazystr +from django.utils.http import MAX_URL_LENGTH class QueryDictTests(SimpleTestCase): @@ -490,6 +491,7 @@ def test_unsafe_redirect(self): 'data:text/html,<script>window.alert("xss")</script>', "mailto:test@example.com", "file:///etc/passwd", + "é" * (MAX_URL_LENGTH + 1), ] for url in bad_urls: with self.assertRaises(DisallowedRedirect):
4f5d904b6375[5.2.x] Fixed CVE-2025-64458 -- Mitigated potential DoS in HttpResponseRedirect/HttpResponsePermanentRedirect on Windows.
5 files changed · +37 −4
django/http/response.py+7 −2 modified@@ -22,7 +22,7 @@ from django.utils.datastructures import CaseInsensitiveMapping from django.utils.encoding import iri_to_uri from django.utils.functional import cached_property -from django.utils.http import content_disposition_header, http_date +from django.utils.http import MAX_URL_LENGTH, content_disposition_header, http_date from django.utils.regex_helper import _lazy_re_compile _charset_from_content_type_re = _lazy_re_compile( @@ -630,7 +630,12 @@ class HttpResponseRedirectBase(HttpResponse): def __init__(self, redirect_to, preserve_request=False, *args, **kwargs): super().__init__(*args, **kwargs) self["Location"] = iri_to_uri(redirect_to) - parsed = urlsplit(str(redirect_to)) + redirect_to_str = str(redirect_to) + if len(redirect_to_str) > MAX_URL_LENGTH: + raise DisallowedRedirect( + f"Unsafe redirect exceeding {MAX_URL_LENGTH} characters" + ) + parsed = urlsplit(redirect_to_str) if preserve_request: self.status_code = self.status_code_preserve_request if parsed.scheme and parsed.scheme not in self.allowed_schemes:
docs/releases/4.2.26.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 4.2.26 release notes Django 4.2.26 fixes one security issue with severity "high" and one security issue with severity "moderate" in 4.2.25. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
docs/releases/5.1.14.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 5.1.14 release notes Django 5.1.14 fixes one security issue with severity "high" and one security issue with severity "moderate" in 5.1.13. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
docs/releases/5.2.8.txt+10 −0 modified@@ -8,6 +8,16 @@ Django 5.2.8 fixes one security issue with severity "high", one security issue with severity "moderate", and several bugs in 5.2.7. It also adds compatibility with Python 3.14. +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`). + Bugfixes ========
tests/httpwrappers/tests.py+2 −0 modified@@ -24,6 +24,7 @@ ) from django.test import SimpleTestCase from django.utils.functional import lazystr +from django.utils.http import MAX_URL_LENGTH class QueryDictTests(SimpleTestCase): @@ -490,6 +491,7 @@ def test_unsafe_redirect(self): 'data:text/html,<script>window.alert("xss")</script>', "mailto:test@example.com", "file:///etc/passwd", + "é" * (MAX_URL_LENGTH + 1), ] for url in bad_urls: with self.assertRaises(DisallowedRedirect):
6e13348436fc[6.0.x] Fixed CVE-2025-64458 -- Mitigated potential DoS in HttpResponseRedirect/HttpResponsePermanentRedirect on Windows.
5 files changed · +37 −4
django/http/response.py+7 −2 modified@@ -22,7 +22,7 @@ from django.utils.datastructures import CaseInsensitiveMapping from django.utils.encoding import iri_to_uri from django.utils.functional import cached_property -from django.utils.http import content_disposition_header, http_date +from django.utils.http import MAX_URL_LENGTH, content_disposition_header, http_date from django.utils.regex_helper import _lazy_re_compile _charset_from_content_type_re = _lazy_re_compile( @@ -631,7 +631,12 @@ class HttpResponseRedirectBase(HttpResponse): def __init__(self, redirect_to, preserve_request=False, *args, **kwargs): super().__init__(*args, **kwargs) self["Location"] = iri_to_uri(redirect_to) - parsed = urlsplit(str(redirect_to)) + redirect_to_str = str(redirect_to) + if len(redirect_to_str) > MAX_URL_LENGTH: + raise DisallowedRedirect( + f"Unsafe redirect exceeding {MAX_URL_LENGTH} characters" + ) + parsed = urlsplit(redirect_to_str) if preserve_request: self.status_code = self.status_code_preserve_request if parsed.scheme and parsed.scheme not in self.allowed_schemes:
docs/releases/4.2.26.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 4.2.26 release notes Django 4.2.26 fixes one security issue with severity "high" and one security issue with severity "moderate" in 4.2.25. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
docs/releases/5.1.14.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 5.1.14 release notes Django 5.1.14 fixes one security issue with severity "high" and one security issue with severity "moderate" in 5.1.13. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
docs/releases/5.2.8.txt+10 −0 modified@@ -8,6 +8,16 @@ Django 5.2.8 fixes one security issue with severity "high", one security issue with severity "moderate", and several bugs in 5.2.7. It also adds compatibility with Python 3.14. +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`). + Bugfixes ========
tests/httpwrappers/tests.py+2 −0 modified@@ -24,6 +24,7 @@ ) from django.test import SimpleTestCase from django.utils.functional import lazystr +from django.utils.http import MAX_URL_LENGTH class QueryDictTests(SimpleTestCase): @@ -490,6 +491,7 @@ def test_unsafe_redirect(self): 'data:text/html,<script>window.alert("xss")</script>', "mailto:test@example.com", "file:///etc/passwd", + "é" * (MAX_URL_LENGTH + 1), ] for url in bad_urls: with self.assertRaises(DisallowedRedirect):
770eea38d7a0[4.2.x] Fixed CVE-2025-64458 -- Mitigated potential DoS in HttpResponseRedirect/HttpResponsePermanentRedirect on Windows.
5 files changed · +20 −5
django/http/response.py+7 −2 modified@@ -21,7 +21,7 @@ from django.utils import timezone from django.utils.datastructures import CaseInsensitiveMapping from django.utils.encoding import iri_to_uri -from django.utils.http import content_disposition_header, http_date +from django.utils.http import MAX_URL_LENGTH, content_disposition_header, http_date from django.utils.regex_helper import _lazy_re_compile _charset_from_content_type_re = _lazy_re_compile( @@ -614,7 +614,12 @@ class HttpResponseRedirectBase(HttpResponse): def __init__(self, redirect_to, *args, **kwargs): super().__init__(*args, **kwargs) self["Location"] = iri_to_uri(redirect_to) - parsed = urlparse(str(redirect_to)) + redirect_to_str = str(redirect_to) + if len(redirect_to_str) > MAX_URL_LENGTH: + raise DisallowedRedirect( + f"Unsafe redirect exceeding {MAX_URL_LENGTH} characters" + ) + parsed = urlparse(redirect_to_str) if parsed.scheme and parsed.scheme not in self.allowed_schemes: raise DisallowedRedirect( "Unsafe redirect to URL with protocol '%s'" % parsed.scheme
django/utils/html.py+1 −2 modified@@ -9,12 +9,11 @@ from django.core.exceptions import SuspiciousOperation from django.utils.encoding import punycode 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 -MAX_URL_LENGTH = 2048 MAX_STRIP_TAGS_DEPTH = 50 # HTML tag that opens but has no closing ">" after 1k+ chars.
django/utils/http.py+1 −0 modified@@ -47,6 +47,7 @@ RFC3986_GENDELIMS = ":/?#[]@" RFC3986_SUBDELIMS = "!$&'()*+,;=" +MAX_URL_LENGTH = 2048 # TODO: Remove when dropping support for PY38. # Unsafe bytes to be removed per WHATWG spec.
docs/releases/4.2.26.txt+9 −1 modified@@ -7,4 +7,12 @@ Django 4.2.26 release notes Django 4.2.26 fixes one security issue with severity "high" and one security issue with severity "moderate" in 4.2.25. -... +CVE-2025-64458: Potential denial-of-service vulnerability in ``HttpResponseRedirect`` and ``HttpResponsePermanentRedirect`` on Windows +====================================================================================================================================== + +Python's :func:`NFKC normalization <python:unicodedata.normalize>` is slow on +Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`, +:class:`~django.http.HttpResponsePermanentRedirect`, and the shortcut +:func:`redirect() <django.shortcuts.redirect>` were subject to a potential +denial-of-service attack via certain inputs with a very large number of Unicode +characters (follow up to :cve:`2025-27556`).
tests/httpwrappers/tests.py+2 −0 modified@@ -24,6 +24,7 @@ ) from django.test import SimpleTestCase from django.utils.functional import lazystr +from django.utils.http import MAX_URL_LENGTH class QueryDictTests(SimpleTestCase): @@ -490,6 +491,7 @@ def test_unsafe_redirect(self): 'data:text/html,<script>window.alert("xss")</script>', "mailto:test@example.com", "file:///etc/passwd", + "é" * (MAX_URL_LENGTH + 1), ] for url in bad_urls: with self.assertRaises(DisallowedRedirect):
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- docs.djangoproject.com/en/dev/releases/security/mitrevendor-advisory
- github.com/advisories/GHSA-qw25-v68c-qjf3ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-64458ghsaADVISORY
- www.djangoproject.com/weblog/2025/nov/05/security-releases/mitrevendor-advisory
- docs.djangoproject.com/en/dev/releases/securityghsaWEB
- github.com/django/django/commit/3790593781d26168e7306b5b2f8ea0309de16242ghsaWEB
- github.com/django/django/commit/4f5d904b63751dea9ffc3b0e046404a7fa5881acghsaWEB
- github.com/django/django/commit/6e13348436fccf8f22982921d6a3a3e65c956a9fghsaWEB
- github.com/django/django/commit/770eea38d7a0e9ba9455140b5a9a9e33618226a7ghsaWEB
- groups.google.com/g/django-announceghsamailing-listWEB
- www.djangoproject.com/weblog/2025/nov/05/security-releasesghsaWEB
News mentions
0No linked articles in our index yet.