1
0
forked from pool/python-Django

12 Commits

Author SHA256 Message Date
1cb7e345a7 Accepting request 1315976 from devel:languages:python:django
Forwarded request #1315948 from mcalabkova

- Update to 5.2.8 (bsc#1252926)
    * CVE-2025-64459: Potential SQL injection via _connector keyword argument
    * Added compatibility for oracledb 3.4.0
    * Fixed a bug in Django 5.2 where QuerySet.first() and QuerySet.last()
      raised an error on querysets performing aggregation that selected all
      fields of a composite primary key.

OBS-URL: https://build.opensuse.org/request/show/1315976
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-Django?expand=0&rev=140
2025-11-07 17:20:57 +00:00
fdcf2d256d - Update to 5.2.8 (bsc#1252926)
* CVE-2025-64459: Potential SQL injection via _connector keyword argument
  * Added compatibility for oracledb 3.4.0
  * Fixed a bug in Django 5.2 where QuerySet.first() and QuerySet.last()
    raised an error on querysets performing aggregation that selected all
    fields of a composite primary key.

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:django/python-Django?expand=0&rev=218
2025-11-06 09:57:16 +00:00
17b3c221a5 Accepting request 1308583 from devel:languages:python:django
OBS-URL: https://build.opensuse.org/request/show/1308583
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-Django?expand=0&rev=139
2025-10-03 13:42:46 +00:00
be4f1447ca - Update to 5.2.7 (bsc#1250485, bsc#1250487)
* CVE-2025-59681: Potential SQL injection in QuerySet.annotate(), alias(),
    aggregate(), and extra() on MySQL and MariaDB
  * CVE-2025-59682: Potential partial directory-traversal via archive.extract()
  * Fixed a regression in Django 5.2 that reduced the color contrast of the
    label of filter_horizontal and filter_vertical widgets within a TabularInline

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:django/python-Django?expand=0&rev=216
2025-10-02 10:47:09 +00:00
878b120faf Accepting request 1302720 from devel:languages:python:django
OBS-URL: https://build.opensuse.org/request/show/1302720
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-Django?expand=0&rev=138
2025-09-05 19:42:17 +00:00
98f379ab77 - Update to 5.2.6 (bsc#1248810)
* CVE-2025-57833: Potential SQL injection in FilteredRelation column aliases
  * Fixed a bug where using QuerySet.values() or values_list() with a ForeignObject
    composed of multiple fields returned incorrect results instead of tuples of
    the referenced fields
- Rebased test_strip_tags.patch

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:django/python-Django?expand=0&rev=214
2025-09-04 11:14:46 +00:00
c617be0174 Accepting request 1299114 from devel:languages:python:django
OBS-URL: https://build.opensuse.org/request/show/1299114
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-Django?expand=0&rev=137
2025-08-13 14:23:21 +00:00
9d51974b18 - Update to 5.2.5
* Fixed a regression in Django 5.2.1 that prevented the usage of UNNEST
    PostgreSQL strategy of QuerySet.bulk_create() with foreign keys
  * Fixed a crash in Django 5.2 when filtering against a composite primary key
    using a tuple containing expressions
  * Fixed a crash in Django 5.2 when validating a model that uses
    GeneratedField or constraints composed of Q and Case lookups
  * Added compatibility for docutils 0.22
  * Fixed a crash in Django 5.2 when using a ManyToManyField on a model with
    a composite primary key, by extending the fields.E347 system check
- Convert to libalternatives on SLE-16-based and newer systems

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:django/python-Django?expand=0&rev=212
2025-08-12 15:39:39 +00:00
78db34879c Accepting request 1296919 from devel:languages:python:django
- Reinstate Requires on tzdata, a lot of packages use it.

OBS-URL: https://build.opensuse.org/request/show/1296919
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-Django?expand=0&rev=136
2025-08-03 11:36:22 +00:00
b367c16b9f - Reinstate Requires on tzdata, a lot of packages use it.
OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:django/python-Django?expand=0&rev=210
2025-08-01 02:09:29 +00:00
33a429e3af Accepting request 1296418 from devel:languages:python:django
- Add patch support-msgfmt-0.25.patch:
  * Support msgfmt 0.25 error messages changes. (bsc#1246966)
- Remove unneeded Requires on tzdata.

OBS-URL: https://build.opensuse.org/request/show/1296418
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-Django?expand=0&rev=135
2025-07-31 15:44:58 +00:00
c5bef52b95 - Add patch support-msgfmt-0.25.patch:
* Support msgfmt 0.25 error messages changes. (bsc#1246966)
- Remove unneeded Requires on tzdata.

OBS-URL: https://build.opensuse.org/package/show/devel:languages:python:django/python-Django?expand=0&rev=208
2025-07-30 06:04:11 +00:00
12 changed files with 284 additions and 434 deletions

View File

@@ -1,82 +0,0 @@
From 4c044fcc866ec226f612c475950b690b0139d243 Mon Sep 17 00:00:00 2001
From: Jake Howard <git@theorangeone.net>
Date: Wed, 13 Aug 2025 14:13:42 +0200
Subject: [PATCH] [5.2.x] Fixed CVE-2025-57833 -- Protected FilteredRelation
against SQL injection in column aliases.
Thanks Eyal Gabay (EyalSec) for the report.
Backport of 51711717098d3f469f795dfa6bc3758b24f69ef7 from main.
---
django/db/models/sql/query.py | 1 +
docs/releases/4.2.24.txt | 7 +++++++
docs/releases/5.1.12.txt | 7 +++++++
docs/releases/5.2.6.txt | 7 +++++++
tests/annotations/tests.py | 24 ++++++++++++++++++++++++
5 files changed, 46 insertions(+)
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 9b44d017ffe3..5247616086aa 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1696,6 +1696,7 @@ def _add_q(
return target_clause, needed_inner
def add_filtered_relation(self, filtered_relation, alias):
+ self.check_alias(alias)
filtered_relation.alias = alias
relation_lookup_parts, relation_field_parts, _ = self.solve_lookup_type(
filtered_relation.relation_name
diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py
index 6c0d7b668c33..060d6324c74c 100644
--- a/tests/annotations/tests.py
+++ b/tests/annotations/tests.py
@@ -14,6 +14,7 @@
Exists,
ExpressionWrapper,
F,
+ FilteredRelation,
FloatField,
Func,
IntegerField,
@@ -1164,6 +1165,15 @@ def test_alias_sql_injection(self):
with self.assertRaisesMessage(ValueError, msg):
Book.objects.annotate(**{crafted_alias: Value(1)})
+ def test_alias_filtered_relation_sql_injection(self):
+ crafted_alias = """injected_name" from "annotations_book"; --"""
+ msg = (
+ "Column aliases cannot contain whitespace characters, quotation marks, "
+ "semicolons, or SQL comments."
+ )
+ with self.assertRaisesMessage(ValueError, msg):
+ Book.objects.annotate(**{crafted_alias: FilteredRelation("author")})
+
def test_alias_forbidden_chars(self):
tests = [
'al"ias',
@@ -1189,6 +1199,11 @@ def test_alias_forbidden_chars(self):
with self.assertRaisesMessage(ValueError, msg):
Book.objects.annotate(**{crafted_alias: Value(1)})
+ with self.assertRaisesMessage(ValueError, msg):
+ Book.objects.annotate(
+ **{crafted_alias: FilteredRelation("authors")}
+ )
+
@skipUnless(connection.vendor == "postgresql", "PostgreSQL tests")
@skipUnlessDBFeature("supports_json_field")
def test_set_returning_functions(self):
@@ -1482,3 +1497,12 @@ def test_alias_sql_injection(self):
)
with self.assertRaisesMessage(ValueError, msg):
Book.objects.alias(**{crafted_alias: Value(1)})
+
+ def test_alias_filtered_relation_sql_injection(self):
+ crafted_alias = """injected_name" from "annotations_book"; --"""
+ msg = (
+ "Column aliases cannot contain whitespace characters, quotation marks, "
+ "semicolons, or SQL comments."
+ )
+ with self.assertRaisesMessage(ValueError, msg):
+ Book.objects.alias(**{crafted_alias: FilteredRelation("authors")})

View File

@@ -1,173 +0,0 @@
From b4d3036c04ae71d611edecf5cfc7d4e5b5927f81 Mon Sep 17 00:00:00 2001
From: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Date: Wed, 10 Sep 2025 09:53:52 +0200
Subject: [PATCH 1/2] [5.2.x] Fixed CVE-2025-59681 -- Protected
QuerySet.annotate(), alias(), aggregate(), and extra() against SQL injection
in column aliases on MySQL/MariaDB.
Thanks sw0rd1ight for the report.
Follow up to 93cae5cb2f9a4ef1514cf1a41f714fef08005200.
---
django/db/models/sql/query.py | 8 ++++----
docs/releases/4.2.25.txt | 9 ++++++++-
docs/releases/5.1.13.txt | 9 ++++++++-
docs/releases/5.2.7.txt | 9 +++++++++
tests/aggregation/tests.py | 4 ++--
tests/annotations/tests.py | 23 ++++++++++++-----------
tests/expressions/test_queryset_values.py | 8 ++++----
tests/queries/tests.py | 4 ++--
8 files changed, 49 insertions(+), 25 deletions(-)
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 5247616086..3a1cd73951 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -48,9 +48,9 @@ from django.utils.tree import Node
__all__ = ["Query", "RawQuery"]
-# Quotation marks ('"`[]), whitespace characters, semicolons, or inline
+# Quotation marks ('"`[]), whitespace characters, semicolons, hashes, or inline
# SQL comments are forbidden in column aliases.
-FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|--|/\*|\*/")
+FORBIDDEN_ALIAS_PATTERN = _lazy_re_compile(r"['`\"\]\[;\s]|#|--|/\*|\*/")
# Inspired from
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
@@ -1208,8 +1208,8 @@ class Query(BaseExpression):
def check_alias(self, alias):
if FORBIDDEN_ALIAS_PATTERN.search(alias):
raise ValueError(
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, "
+ "quotation marks, semicolons, or SQL comments."
)
def add_annotation(self, annotation, alias, select=True):
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index bf44c4d25f..2e41f19947 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -2136,8 +2136,8 @@ class AggregateTestCase(TestCase):
def test_alias_sql_injection(self):
crafted_alias = """injected_name" from "aggregation_author"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Author.objects.aggregate(**{crafted_alias: Avg("age")})
diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py
index 060d6324c7..7a12121224 100644
--- a/tests/annotations/tests.py
+++ b/tests/annotations/tests.py
@@ -1159,8 +1159,8 @@ class NonAggregateAnnotationTestCase(TestCase):
def test_alias_sql_injection(self):
crafted_alias = """injected_name" from "annotations_book"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Book.objects.annotate(**{crafted_alias: Value(1)})
@@ -1168,8 +1168,8 @@ class NonAggregateAnnotationTestCase(TestCase):
def test_alias_filtered_relation_sql_injection(self):
crafted_alias = """injected_name" from "annotations_book"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Book.objects.annotate(**{crafted_alias: FilteredRelation("author")})
@@ -1186,13 +1186,14 @@ class NonAggregateAnnotationTestCase(TestCase):
"ali/*as",
"alias*/",
"alias;",
- # [] are used by MSSQL.
+ # [] and # are used by MSSQL.
"alias[",
"alias]",
+ "ali#as",
]
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
for crafted_alias in tests:
with self.subTest(crafted_alias):
@@ -1492,8 +1493,8 @@ class AliasTests(TestCase):
def test_alias_sql_injection(self):
crafted_alias = """injected_name" from "annotations_book"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Book.objects.alias(**{crafted_alias: Value(1)})
@@ -1501,8 +1502,8 @@ class AliasTests(TestCase):
def test_alias_filtered_relation_sql_injection(self):
crafted_alias = """injected_name" from "annotations_book"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Book.objects.alias(**{crafted_alias: FilteredRelation("authors")})
diff --git a/tests/expressions/test_queryset_values.py b/tests/expressions/test_queryset_values.py
index 47bd1358de..080ee06183 100644
--- a/tests/expressions/test_queryset_values.py
+++ b/tests/expressions/test_queryset_values.py
@@ -37,8 +37,8 @@ class ValuesExpressionsTests(TestCase):
def test_values_expression_alias_sql_injection(self):
crafted_alias = """injected_name" from "expressions_company"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Company.objects.values(**{crafted_alias: F("ceo__salary")})
@@ -47,8 +47,8 @@ class ValuesExpressionsTests(TestCase):
def test_values_expression_alias_sql_injection_json_field(self):
crafted_alias = """injected_name" from "expressions_company"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
JSONFieldModel.objects.values(f"data__{crafted_alias}")
diff --git a/tests/queries/tests.py b/tests/queries/tests.py
index 38b0a5ddfa..ffaabf48a0 100644
--- a/tests/queries/tests.py
+++ b/tests/queries/tests.py
@@ -1961,8 +1961,8 @@ class Queries5Tests(TestCase):
def test_extra_select_alias_sql_injection(self):
crafted_alias = """injected_name" from "queries_note"; --"""
msg = (
- "Column aliases cannot contain whitespace characters, quotation marks, "
- "semicolons, or SQL comments."
+ "Column aliases cannot contain whitespace characters, hashes, quotation "
+ "marks, semicolons, or SQL comments."
)
with self.assertRaisesMessage(ValueError, msg):
Note.objects.extra(select={crafted_alias: "1"})
--
2.39.5 (Apple Git-154)

View File

@@ -1,74 +0,0 @@
From 3a7091babcb19f213a25dd5bf8ad90fd63c3cba0 Mon Sep 17 00:00:00 2001
From: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
Date: Tue, 16 Sep 2025 17:13:36 +0200
Subject: [PATCH 2/2] [5.2.x] Fixed CVE-2025-59682 -- Fixed potential partial
directory-traversal via archive.extract().
Thanks stackered for the report.
Follow up to 05413afa8c18cdb978fcdf470e09f7a12b234a23.
---
django/utils/archive.py | 6 +++++-
docs/releases/4.2.25.txt | 8 ++++++++
docs/releases/5.1.13.txt | 8 ++++++++
docs/releases/5.2.7.txt | 8 ++++++++
tests/utils_tests/test_archive.py | 22 ++++++++++++++++++++++
5 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/django/utils/archive.py b/django/utils/archive.py
index 56f34c0038..c05fbcdc97 100644
--- a/django/utils/archive.py
+++ b/django/utils/archive.py
@@ -145,7 +145,11 @@ class BaseArchive:
def target_filename(self, to_path, name):
target_path = os.path.abspath(to_path)
filename = os.path.abspath(os.path.join(target_path, name))
- if not filename.startswith(target_path):
+ try:
+ if os.path.commonpath([target_path, filename]) != target_path:
+ raise SuspiciousOperation("Archive contains invalid path: '%s'" % name)
+ except ValueError:
+ # Different drives on Windows raises ValueError.
raise SuspiciousOperation("Archive contains invalid path: '%s'" % name)
return filename
diff --git a/tests/utils_tests/test_archive.py b/tests/utils_tests/test_archive.py
index 89a45bc072..24e60039a5 100644
--- a/tests/utils_tests/test_archive.py
+++ b/tests/utils_tests/test_archive.py
@@ -3,6 +3,7 @@ import stat
import sys
import tempfile
import unittest
+import zipfile
from django.core.exceptions import SuspiciousOperation
from django.test import SimpleTestCase
@@ -94,3 +95,24 @@ class TestArchiveInvalid(SimpleTestCase):
with self.subTest(entry), tempfile.TemporaryDirectory() as tmpdir:
with self.assertRaisesMessage(SuspiciousOperation, msg % invalid_path):
archive.extract(os.path.join(archives_dir, entry), tmpdir)
+
+ def test_extract_function_traversal_startswith(self):
+ with tempfile.TemporaryDirectory() as tmpdir:
+ base = os.path.abspath(tmpdir)
+ tarfile_handle = tempfile.NamedTemporaryFile(suffix=".zip", delete=False)
+ tar_path = tarfile_handle.name
+
+ try:
+ tarfile_handle.close()
+ malicious_member = os.path.join(base + "abc", "evil.txt")
+
+ with zipfile.ZipFile(tar_path, "w") as zf:
+ zf.writestr(malicious_member, "evil\n")
+ zf.writestr("test.txt", "data\n")
+
+ with self.assertRaisesMessage(
+ SuspiciousOperation, "Archive contains invalid path"
+ ):
+ archive.extract(tar_path, base)
+ finally:
+ os.remove(tar_path)
--
2.39.5 (Apple Git-154)

View File

@@ -1,68 +0,0 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
This file contains MD5, SHA1, and SHA256 checksums for the
source-code tarball and wheel files of Django 5.2.4, released July 2, 2025.
To use this file, you will need a working install of PGP or other
compatible public-key encryption software. You will also need to have
the Django release manager's public key in your keyring. This key has
the ID ``2EE82A8D9470983E`` and can be imported from the MIT
keyserver, for example, if using the open-source GNU Privacy Guard
implementation of PGP:
gpg --keyserver pgp.mit.edu --recv-key 2EE82A8D9470983E
or via the GitHub API:
curl https://github.com/nessita.gpg | gpg --import -
Once the key is imported, verify this file:
gpg --verify Django-5.2.4.checksum.txt
Once you have verified this file, you can use normal MD5, SHA1, or SHA256
checksumming applications to generate the checksums of the Django
package and compare them to the checksums listed below.
Release packages
================
https://www.djangoproject.com/download/5.2.4/tarball/
https://www.djangoproject.com/download/5.2.4/wheel/
MD5 checksums
=============
6ecc4875e8cdc08706faea1cc4740fdf django-5.2.4.tar.gz
fee657f7686462d388f274c5f92b634a django-5.2.4-py3-none-any.whl
SHA1 checksums
==============
de45d44e1bb2ceb1c08b8fd0846de920874f71a1 django-5.2.4.tar.gz
a6a7904e3749a0e8937a50643293889929b4b6f7 django-5.2.4-py3-none-any.whl
SHA256 checksums
================
a1228c384f8fa13eebc015196db7b3e08722c5058d4758d20cb287503a540d8f django-5.2.4.tar.gz
60c35bd96201b10c6e7a78121bd0da51084733efa303cc19ead021ab179cef5e django-5.2.4-py3-none-any.whl
-----BEGIN PGP SIGNATURE-----
iQJcBAEBCABGFiEEW1sboQ2FrHxcduOPLugqjZRwmD4FAmhlfcIoHDEyNDMwNCtu
ZXNzaXRhQHVzZXJzLm5vcmVwbHkuZ2l0aHViLmNvbQAKCRAu6CqNlHCYPj5DD/94
KOuOZ5JHtZWknqi1JeV1akzB/RpY7lhL9SbJbVXhdAxOY9Cn4eUG7NsPWa9JnhX1
F/2geBE5mjOZen4ARtGHWxa5vqidqUbscrU9AkqPLn6aecEKi2jXXNkYmmWw/37K
wb92BQtuWkaXyiZ4E6Sledx9yFhcqMDFg27CdNYfAqUWofI6zzSmLIzOlOSVR9Sc
uDrfRqQ4GXlRGT5pIkcIxE0ZKToUYrKgn99PZOmBcLfJgQ4VBt62J6SzZAhhElb3
DUMcVhG2XNIhg7v7DwlVodowDYQdRi2H/ahAa7/m1+uugRbysoGSLLwP+50tDjlj
07zxoJsrL5R9zaMp4pcXQN4bUy3rDz94DkjlXO51f8LwDdStvk4VOYan1W5S9BhP
R0conCFfcg4+iK0pV5e/GeeTwBRHQw8p5RuWfrEpKFi/XQtT0u01hqUGppeuZ9wI
f+Ud9RA8Nrw0ouli4WvfH0RVFuMgUFqScwO88oatuUH5CDPjlV+5usNb7FrmZXv6
AWRopONOcYGF07+FYh0nsoE8enWyxE+JWTJzxT5PGZ3buUO0hlnJ+auoJv8yOVii
ELCSUyi93glWonCBrS41XrNO6+6K/8V9V6iv9/PdGwF1GszbX5Rx4e2lDMA7crYh
1qKGaV3+iAO+Y+vXt6VTy6h5GLg9hun+RQ8TU3Guyg==
=d9C5
-----END PGP SIGNATURE-----

68
Django-5.2.8.checksum.txt Normal file
View File

@@ -0,0 +1,68 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256
This file contains MD5, SHA1, and SHA256 checksums for the
source-code tarball and wheel files of Django 5.2.8, released November 5, 2025.
To use this file, you will need a working install of PGP or other
compatible public-key encryption software. You will also need to have
the Django release manager's public key in your keyring. This key has
the ID ``2EE82A8D9470983E`` and can be imported from the MIT
keyserver, for example, if using the open-source GNU Privacy Guard
implementation of PGP:
gpg --keyserver pgp.mit.edu --recv-key 2EE82A8D9470983E
or via the GitHub API:
curl https://github.com/nessita.gpg | gpg --import -
Once the key is imported, verify this file:
gpg --verify Django-5.2.8.checksum.txt
Once you have verified this file, you can use normal MD5, SHA1, or SHA256
checksumming applications to generate the checksums of the Django
package and compare them to the checksums listed below.
Release packages
================
https://www.djangoproject.com/download/5.2.8/tarball/
https://www.djangoproject.com/download/5.2.8/wheel/
MD5 checksums
=============
0268c52cb99bb764490fdd90502def32 django-5.2.8.tar.gz
60ed4555e2f91cc881b2293ad78bf423 django-5.2.8-py3-none-any.whl
SHA1 checksums
==============
41d50f7b49e3c60ad0e3e873c1474f883640d179 django-5.2.8.tar.gz
50d9ad23cef8ebe6cc7d17004e65ae6b5dbabc37 django-5.2.8-py3-none-any.whl
SHA256 checksums
================
23254866a5bb9a2cfa6004e8b809ec6246eba4b58a7589bc2772f1bcc8456c7f django-5.2.8.tar.gz
37e687f7bd73ddf043e2b6b97cfe02fcbb11f2dbb3adccc6a2b18c6daa054d7f django-5.2.8-py3-none-any.whl
-----BEGIN PGP SIGNATURE-----
iQJcBAEBCABGFiEEW1sboQ2FrHxcduOPLugqjZRwmD4FAmkLRQooHDEyNDMwNCtu
ZXNzaXRhQHVzZXJzLm5vcmVwbHkuZ2l0aHViLmNvbQAKCRAu6CqNlHCYPsFxD/4h
zgUToQHe7WgIhVOHKe2ARgXDhA/4yooteYTLoFl6vFzt4r+h+7/3LH8/XucJwYWa
O9SimNT0MhtcWKM0l3jczGMhr3pH7zeBUExtzyPVyycTyQ5KgbDVEgf+w4ua+Jo3
BzQBnUkJN9Ofc/uQqIAj0X3zjp9NE7uNZpOLzpRUwulrUQ7ieFAAhs3JrCM2mmTF
KnudQkY50zIHy9OX8mSvF8OslFQ9Z84ZPlHfqaQzN6uDNIRujMu9sSbvbiWgpQ9h
Tp/MVRppmlKXcZjM5M+vT0sqT4Ac/OepkSSVMSKAKHNPOpsG3wC/ouclkgG6Wv2Z
6r6Ea2LND8HoMHUhScir558g3pF6p9NW5vrK3Qd7cS4G6idv2eVzzHqYH8WORG9s
5HnldOGhRF6ONAwSveEbViQ6/fzWYsROrCa5+IOfELtg7Uc+ji3eQSqFvyR7rPxt
Ux+LVvgWfODNEjTlrqZQDaPDU4P7gy6So5vzXe+eciyyNxgftmlpWSHMliXcYjxo
gxUh6EPjklxFQ8fmFecCz57CJ0oXT2qB3iNDyTft3qqetgWeJ72d9rVMLLXmHLOe
oRKFS3QXXBr+sIdxWB2Fgu2g8X5ky3O9wIgN7OzQ2p4pCja+NSmxlhJxJwUomgjA
UHvOPP6hwSp1TQdcoauXD72A+t0TkYLuZ03Dfzkh1Q==
=ci0h
-----END PGP SIGNATURE-----

View File

@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a1228c384f8fa13eebc015196db7b3e08722c5058d4758d20cb287503a540d8f
size 10831909

3
django-5.2.8.tar.gz Normal file
View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:23254866a5bb9a2cfa6004e8b809ec6246eba4b58a7589bc2772f1bcc8456c7f
size 10849032

View File

@@ -1,14 +1,59 @@
-------------------------------------------------------------------
Thu Oct 2 10:01:50 UTC 2025 - Markéta Machová <mmachova@suse.com>
Thu Nov 6 07:20:08 UTC 2025 - Markéta Machová <mmachova@suse.com>
- Add security patches:
* CVE-2025-59681.patch (bsc#1250485)
* CVE-2025-59682.patch (bsc#1250487)
- Update to 5.2.8 (bsc#1252926)
* CVE-2025-64459: Potential SQL injection via _connector keyword argument
* Added compatibility for oracledb 3.4.0
* Fixed a bug in Django 5.2 where QuerySet.first() and QuerySet.last()
raised an error on querysets performing aggregation that selected all
fields of a composite primary key.
-------------------------------------------------------------------
Thu Sep 4 13:14:40 UTC 2025 - Markéta Machová <mmachova@suse.com>
Thu Oct 2 09:41:30 UTC 2025 - Markéta Machová <mmachova@suse.com>
- Add security patch CVE-2025-57833.patch (bsc#1248810)
- Update to 5.2.7 (bsc#1250485, bsc#1250487)
* CVE-2025-59681: Potential SQL injection in QuerySet.annotate(), alias(),
aggregate(), and extra() on MySQL and MariaDB
* CVE-2025-59682: Potential partial directory-traversal via archive.extract()
* Fixed a regression in Django 5.2 that reduced the color contrast of the
label of filter_horizontal and filter_vertical widgets within a TabularInline
-------------------------------------------------------------------
Thu Sep 4 10:02:00 UTC 2025 - Markéta Machová <mmachova@suse.com>
- Update to 5.2.6 (bsc#1248810)
* CVE-2025-57833: Potential SQL injection in FilteredRelation column aliases
* Fixed a bug where using QuerySet.values() or values_list() with a ForeignObject
composed of multiple fields returned incorrect results instead of tuples of
the referenced fields
- Rebased test_strip_tags.patch
-------------------------------------------------------------------
Tue Aug 12 10:52:26 UTC 2025 - Markéta Machová <mmachova@suse.com>
- Update to 5.2.5
* Fixed a regression in Django 5.2.1 that prevented the usage of UNNEST
PostgreSQL strategy of QuerySet.bulk_create() with foreign keys
* Fixed a crash in Django 5.2 when filtering against a composite primary key
using a tuple containing expressions
* Fixed a crash in Django 5.2 when validating a model that uses
GeneratedField or constraints composed of Q and Case lookups
* Added compatibility for docutils 0.22
* Fixed a crash in Django 5.2 when using a ManyToManyField on a model with
a composite primary key, by extending the fields.E347 system check
- Convert to libalternatives on SLE-16-based and newer systems
-------------------------------------------------------------------
Fri Aug 1 02:09:01 UTC 2025 - Steve Kowalik <steven.kowalik@suse.com>
- Reinstate Requires on tzdata, a lot of packages use it.
-------------------------------------------------------------------
Wed Jul 30 06:03:44 UTC 2025 - Steve Kowalik <steven.kowalik@suse.com>
- Add patch support-msgfmt-0.25.patch:
* Support msgfmt 0.25 error messages changes. (bsc#1246966)
- Remove unneeded Requires on tzdata.
-------------------------------------------------------------------
Sat Jul 19 06:51:37 UTC 2025 - Markéta Machová <mmachova@suse.com>

View File

@@ -130,3 +130,55 @@ BzeRu0mAvjLkLNegQIvfdVXfYIcwUQQB8OAzoz3qzi8vji82MBQO+gkYrlteivoF
z+gZLcBuv/NdNg==
=B8gH
-----END PGP PUBLIC KEY BLOCK-----
-----BEGIN PGP PUBLIC KEY BLOCK-----
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
R182g26K1DaCZphtoq8Z
=0YqB
-----END PGP PUBLIC KEY BLOCK-----

View File

@@ -1,7 +1,7 @@
#
# spec file for package python-Django
#
# Copyright (c) 2025 SUSE LLC
# Copyright (c) 2025 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -20,8 +20,13 @@
%bcond_with selenium
%bcond_with memcached
%{?sle15_python_module_pythons}
%if 0%{?suse_version} > 1500
%bcond_without libalternatives
%else
%bcond_with libalternatives
%endif
Name: python-Django
Version: 5.2.4
Version: 5.2.8
Release: 0
Summary: A high-level Python Web framework
License: BSD-3-Clause
@@ -31,13 +36,10 @@ Source1: https://www.djangoproject.com/m/pgp/Django-%{version}.checksum.t
Source2: %{name}.keyring
Source99: python-Django-rpmlintrc
# PATCH-FIX-UPSTREAM https://github.com/django/django/pull/19639 Fixed #36499 -- Adjusted utils_tests.test_html.TestUtilsHtml.test_strip_tags following Python's HTMLParser new behavior.
# fixed and refined upstream, but some of our interpreters weren't updated to a new version yet and still only carry the patch, so providing the non-conditional version
Patch0: test_strip_tags.patch
# PATCH-FIX-UPSTREAM CVE-2025-57833.patch bsc#1248810
Patch1: CVE-2025-57833.patch
# PATCH-FIX-UPSTREAM CVE-2025-59681.patch bsc#1250485
Patch2: CVE-2025-59681.patch
# PATCH-FIX-UPSTREAM CVE-2025-59682.patch bsc#1250487
Patch3: CVE-2025-59682.patch
# PATCH-FIX-UPSTREAM https://github.com/django/django/pull/19530 Fixed #36421 -- Made test_msgfmt_error_including_non_ascii compatible with with msgfmt 0.25.
Patch1: support-msgfmt-0.25.patch
BuildRequires: %{python_module Jinja2 >= 2.9.2}
BuildRequires: %{python_module Pillow >= 6.2.0}
BuildRequires: %{python_module PyYAML}
@@ -62,8 +64,6 @@ Requires: python
Requires: python-asgiref >= 3.7.0
Requires: python-sqlparse >= 0.3.1
Requires: python-tzdata
Requires(post): update-alternatives
Requires(postun): update-alternatives
Recommends: python-Jinja2 >= 2.9.2
Recommends: python-Pillow >= 6.2.0
Recommends: python-PyYAML
@@ -77,6 +77,13 @@ Obsoletes: python-django < %{version}
Provides: python-South = %{version}
Obsoletes: python-South < %{version}
BuildArch: noarch
%if %{with libalternatives}
BuildRequires: alts
Requires: alts
%else
Requires(post): update-alternatives
Requires(postun): update-alternatives
%endif
%if %{with memcached}
BuildRequires: %{python_module pylibmc}
BuildRequires: %{python_module pymemcache}
@@ -137,6 +144,9 @@ export PATH=%{_libdir}/chromium:$PATH
%python_expand PYTHONPATH=.:%{buildroot}%{$python_sitelib} $python tests/runtests.py -v 2
%endif
%pre
%python_libalternatives_reset_alternative django-admin
%post
%{python_install_alternative django-admin}

69
support-msgfmt-0.25.patch Normal file
View File

@@ -0,0 +1,69 @@
From 3609c463a4cfc5a7e76f4d4ba008c5096b1f1437 Mon Sep 17 00:00:00 2001
From: Jericho Serrano <118679068+jericho1050@users.noreply.github.com>
Date: Fri, 6 Jun 2025 04:58:29 +0800
Subject: [PATCH] Fixed #36421 -- Made test_msgfmt_error_including_non_ascii
compatible with msgfmt 0.25.
---
tests/i18n/test_compilation.py | 25 +++++++++++++++++++++++--
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/tests/i18n/test_compilation.py b/tests/i18n/test_compilation.py
index 4b0bb9f6bb1..3a57dbf0765 100644
--- a/tests/i18n/test_compilation.py
+++ b/tests/i18n/test_compilation.py
@@ -1,5 +1,6 @@
import gettext as gettext_module
import os
+import re
import stat
import unittest
from io import StringIO
@@ -8,10 +9,12 @@
from unittest import mock
from django.core.management import CommandError, call_command, execute_from_command_line
-from django.core.management.utils import find_command
+from django.core.management.utils import find_command, popen_wrapper
from django.test import SimpleTestCase, override_settings
from django.test.utils import captured_stderr, captured_stdout
from django.utils import translation
+from django.utils.encoding import DEFAULT_LOCALE_ENCODING
+from django.utils.functional import cached_property
from django.utils.translation import gettext
from .utils import RunInTmpDirMixin, copytree
@@ -254,6 +257,17 @@ def test_no_dirs_accidentally_skipped(self):
class CompilationErrorHandling(MessageCompilationTests):
+ @cached_property
+ def msgfmt_version(self):
+ # Note that msgfmt is installed via GNU gettext tools, hence the msgfmt
+ # version should align to gettext.
+ out, err, status = popen_wrapper(
+ ["msgfmt", "--version"],
+ stdout_encoding=DEFAULT_LOCALE_ENCODING,
+ )
+ m = re.search(r"(\d+)\.(\d+)\.?(\d+)?", out)
+ return tuple(int(d) for d in m.groups() if d is not None)
+
def test_error_reported_by_msgfmt(self):
# po file contains wrong po formatting.
with self.assertRaises(CommandError):
@@ -278,7 +292,14 @@ def test_msgfmt_error_including_non_ascii(self):
call_command(
"compilemessages", locale=["ko"], stdout=StringIO(), stderr=stderr
)
- self.assertIn("' cannot start a field name", stderr.getvalue())
+ if self.msgfmt_version < (0, 25):
+ error_msg = "' cannot start a field name"
+ else:
+ error_msg = (
+ "a field name starts with a character that is not alphanumerical "
+ "or underscore"
+ )
+ self.assertIn(error_msg, stderr.getvalue())
class ProjectAndAppTests(MessageCompilationTests):

View File

@@ -10,11 +10,11 @@ Subject: [PATCH] Fixed #36499 -- Adjusted
tests/utils_tests/test_html.py | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/test_utils/tests.py b/tests/test_utils/tests.py
index 494a0ea8d384..0de19eae9072 100644
--- a/tests/test_utils/tests.py
+++ b/tests/test_utils/tests.py
@@ -959,10 +959,10 @@ def test_parsing_errors(self):
Index: django-5.2.6/tests/test_utils/tests.py
===================================================================
--- django-5.2.6.orig/tests/test_utils/tests.py
+++ django-5.2.6/tests/test_utils/tests.py
@@ -945,10 +945,10 @@ class HTMLEqualTests(SimpleTestCase):
self.assertHTMLEqual("", "<p>")
error_msg = (
"First argument is not valid HTML:\n"
@@ -22,25 +22,28 @@ index 494a0ea8d384..0de19eae9072 100644
+ "('Unexpected end tag `div` (Line 1, Column 0)', (1, 0))"
)
with self.assertRaisesMessage(AssertionError, error_msg):
- self.assertHTMLEqual("< div></ div>", "<div></div>")
- self.assertHTMLEqual("< div></div>", "<div></div>")
+ self.assertHTMLEqual("</div>", "<div></div>")
with self.assertRaises(HTMLParseError):
parse_html("</p>")
diff --git a/tests/utils_tests/test_html.py b/tests/utils_tests/test_html.py
index 4ce552e79a0d..205eaeca1668 100644
--- a/tests/utils_tests/test_html.py
+++ b/tests/utils_tests/test_html.py
@@ -142,10 +142,10 @@ def test_strip_tags(self):
("&gotcha&#;<>", "&gotcha&#;<>"),
("<sc<!-- -->ript>test<<!-- -->/script>", "ript>test"),
Index: django-5.2.6/tests/utils_tests/test_html.py
===================================================================
--- django-5.2.6.orig/tests/utils_tests/test_html.py
+++ django-5.2.6/tests/utils_tests/test_html.py
@@ -162,13 +162,13 @@ class TestUtilsHtml(SimpleTestCase):
("<script>alert()</script>&h", "alert()h"),
- ("><!" + ("&" * 16000) + "D", "><!" + ("&" * 16000) + "D"),
+ ("><!" + ("&" * 16000) + "D", ">"),
(
"><!" + ("&" * 16000) + "D",
- ">" if htmlparser_fixed else "><!" + ("&" * 16000) + "D",
+ ">",
),
("X<<<<br>br>br>br>X", "XX"),
("<" * 50 + "a>" * 50, ""),
- (">" + "<a" * 500 + "a", ">" + "<a" * 500 + "a"),
+ (">" + "<a" * 500 + "a", ">"),
(
">" + "<a" * 500 + "a",
- ">" if htmlparser_fixed else ">" + "<a" * 500 + "a",
+ ">",
),
("<a" * 49 + "a" * 951, "<a" * 49 + "a" * 951),
("<" + "a" * 1_002, "<" + "a" * 1_002),
)