Security advisory GHSA-6w2r-r2m5-xq5w: Django is subject to SQL injection through its column aliases
Package: django (pypi), vulnerable version: 4.2.23, fixed in: 4.2.24
CWE: CWE-89
Files changed by the fix:
django/db/models/sql/query.py

Fix diff:
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 293856d86fa2..332e4f2ac667 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -1659,6 +1659,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/docs/releases/4.2.24.txt b/docs/releases/4.2.24.txt
index d6e198fb9c0d..e50148391716 100644
--- a/docs/releases/4.2.24.txt
+++ b/docs/releases/4.2.24.txt
@@ -5,3 +5,10 @@ Django 4.2.24 release notes
 *September 3, 2025*
 
 Django 4.2.24 fixes a security issue with severity "high" in 4.2.23.
+
+CVE-2025-57833: Potential SQL injection in ``FilteredRelation`` column aliases
+==============================================================================
+
+:class:`.FilteredRelation` was subject to SQL injection in column aliases,
+using a suitably crafted dictionary, with dictionary expansion, as the
+``**kwargs`` passed to :meth:`.QuerySet.annotate` or :meth:`.QuerySet.alias`.
diff --git a/docs/releases/5.1.12.txt b/docs/releases/5.1.12.txt
index 351d88839868..dbc7ba279ffa 100644
--- a/docs/releases/5.1.12.txt
+++ b/docs/releases/5.1.12.txt
@@ -5,3 +5,10 @@ Django 5.1.12 release notes
 *September 3, 2025*
 
 Django 5.1.12 fixes a security issue with severity "high" in 5.1.11.
+
+CVE-2025-57833: Potential SQL injection in ``FilteredRelation`` column aliases
+==============================================================================
+
+:class:`.FilteredRelation` was subject to SQL injection in column aliases,
+using a suitably crafted dictionary, with dictionary expansion, as the
+``**kwargs`` passed to :meth:`.QuerySet.annotate` or :meth:`.QuerySet.alias`.
diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py
index f1260b41926b..01fa6958db7b 100644
--- a/tests/annotations/tests.py
+++ b/tests/annotations/tests.py
@@ -12,6 +12,7 @@
     Exists,
     ExpressionWrapper,
     F,
+    FilteredRelation,
     FloatField,
     Func,
     IntegerField,
@@ -1132,6 +1133,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',
@@ -1157,6 +1167,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")}
+                    )
+
 
 class AliasTests(TestCase):
     @classmethod
@@ -1429,3 +1444,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")})