From 71c241127add767653b81f9021d7ebf84909389c Mon Sep 17 00:00:00 2001 From: starlet-dx <15929766099@163.com> Date: Thu, 6 Nov 2025 10:02:57 +0800 Subject: [PATCH] Fix CVE-2025-64458 and CVE-2025-64459 (cherry picked from commit f89e84e176440c7a3ca72580e698ecb633e1ac48) --- CVE-2025-64458.patch | 99 ++++++++++++++++++++++++++++++++++++++++++++ CVE-2025-64459.patch | 53 ++++++++++++++++++++++++ python-django.spec | 7 +++- 3 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 CVE-2025-64458.patch create mode 100644 CVE-2025-64459.patch diff --git a/CVE-2025-64458.patch b/CVE-2025-64458.patch new file mode 100644 index 0000000..de73e8b --- /dev/null +++ b/CVE-2025-64458.patch @@ -0,0 +1,99 @@ +From 770eea38d7a0e9ba9455140b5a9a9e33618226a7 Mon Sep 17 00:00:00 2001 +From: Jacob Walls +Date: Thu, 16 Oct 2025 16:28:33 -0400 +Subject: [PATCH] [4.2.x] Fixed CVE-2025-64458 -- Mitigated potential DoS in + HttpResponseRedirect/HttpResponsePermanentRedirect on Windows. + +Thanks Seokchan Yoon for the report, Markus Holtermann for the +triage, and Jake Howard for the review. + +Backport of c880530ddd4fabd5939bab0e148bebe36699432a from main. + +Origin: https://github.com/django/django/commit/770eea38d7a0e9ba9455140b5a9a9e33618226a7 +--- + django/http/response.py | 9 +++++++-- + django/utils/html.py | 3 +-- + django/utils/http.py | 1 + + tests/httpwrappers/tests.py | 2 ++ + 4 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/django/http/response.py b/django/http/response.py +index ea31141..763fd2a 100644 +--- a/django/http/response.py ++++ b/django/http/response.py +@@ -21,7 +21,7 @@ from django.http.cookie import SimpleCookie + 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 +diff --git a/django/utils/html.py b/django/utils/html.py +index 84c37d1..11ffd53 100644 +--- a/django/utils/html.py ++++ b/django/utils/html.py +@@ -9,12 +9,11 @@ from urllib.parse import parse_qsl, quote, unquote, urlencode, urlsplit, urlunsp + 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. +diff --git a/django/utils/http.py b/django/utils/http.py +index 3e7acb5..5c1c6b8 100644 +--- a/django/utils/http.py ++++ b/django/utils/http.py +@@ -46,6 +46,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 + + # TODO: Remove when dropping support for PY38. + # Unsafe bytes to be removed per WHATWG spec. +diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py +index fa2c8fd..b20d9a1 100644 +--- a/tests/httpwrappers/tests.py ++++ b/tests/httpwrappers/tests.py +@@ -24,6 +24,7 @@ from django.http import ( + ) + 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 @@ class HttpResponseTests(SimpleTestCase): + 'data:text/html,', + "mailto:test@example.com", + "file:///etc/passwd", ++ "é" * (MAX_URL_LENGTH + 1), + ] + for url in bad_urls: + with self.assertRaises(DisallowedRedirect): +-- +2.51.1 + diff --git a/CVE-2025-64459.patch b/CVE-2025-64459.patch new file mode 100644 index 0000000..41b5445 --- /dev/null +++ b/CVE-2025-64459.patch @@ -0,0 +1,53 @@ +From 59ae82e67053d281ff4562a24bbba21299f0a7d4 Mon Sep 17 00:00:00 2001 +From: Jacob Walls +Date: Wed, 24 Sep 2025 15:54:51 -0400 +Subject: [PATCH] [4.2.x] Fixed CVE-2025-64459 -- Prevented SQL injections in + Q/QuerySet via the _connector kwarg. + +Thanks cyberstan for the report, Sarah Boyce, Adam Johnson, Simon +Charette, and Jake Howard for the reviews. + +Backport of c880530ddd4fabd5939bab0e148bebe36699432a from main. + +Origin: https://github.com/django/django/commit/59ae82e67053d281ff4562a24bbba21299f0a7d4 +--- + django/db/models/query_utils.py | 4 ++++ + tests/queries/test_q.py | 5 +++++ + 2 files changed, 9 insertions(+) + +diff --git a/django/db/models/query_utils.py b/django/db/models/query_utils.py +index 5c5644c..a85a682 100644 +--- a/django/db/models/query_utils.py ++++ b/django/db/models/query_utils.py +@@ -44,8 +44,12 @@ class Q(tree.Node): + XOR = "XOR" + default = AND + conditional = True ++ connectors = (None, AND, OR, XOR) + + def __init__(self, *args, _connector=None, _negated=False, **kwargs): ++ if _connector not in self.connectors: ++ connector_reprs = ", ".join(f"{conn!r}" for conn in self.connectors[1:]) ++ raise ValueError(f"_connector must be one of {connector_reprs}, or None.") + super().__init__( + children=[*args, *sorted(kwargs.items())], + connector=_connector, +diff --git a/tests/queries/test_q.py b/tests/queries/test_q.py +index cdf4029..5f20a41 100644 +--- a/tests/queries/test_q.py ++++ b/tests/queries/test_q.py +@@ -225,6 +225,11 @@ class QTests(SimpleTestCase): + Q(*items, _connector=connector), + ) + ++ def test_connector_validation(self): ++ msg = f"_connector must be one of {Q.AND!r}, {Q.OR!r}, {Q.XOR!r}, or None." ++ with self.assertRaisesMessage(ValueError, msg): ++ Q(_connector="evil") ++ + + class QCheckTests(TestCase): + def test_basic(self): +-- +2.51.1 + diff --git a/python-django.spec b/python-django.spec index c2106e2..d55f4b8 100644 --- a/python-django.spec +++ b/python-django.spec @@ -1,7 +1,7 @@ %global _empty_manifest_terminate_build 0 Name: python-django Version: 4.2.15 -Release: 9 +Release: 10 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design. License: Apache-2.0 and Python-2.0 and BSD-3-Clause URL: https://www.djangoproject.com/ @@ -19,6 +19,8 @@ Patch9: CVE-2025-48432.patch Patch10: CVE-2025-57833.patch Patch11: CVE-2025-59681.patch Patch12: CVE-2025-59682.patch +Patch13: CVE-2025-64458.patch +Patch14: CVE-2025-64459.patch BuildArch: noarch %description @@ -85,6 +87,9 @@ mv %{buildroot}/doclist.lst . %{_docdir}/* %changelog +* Thu Nov 06 2025 yaoxin <1024769339@qq.com> - 4.2.15-10 +- Fix CVE-2025-64458 and CVE-2025-64459 + * Thu Oct 09 2025 yaoxin <1024769339@qq.com> - 4.2.15-9 - Fix CVE-2025-59681 and CVE-2025-59682 -- Gitee