Skip to content
/ django Public

Commit 005d60d

Browse files
Refs CVE-2026-1312 -- Raised ValueError when FilteredRelation aliases contain periods.
This prevents failures at the database layer, given that aliases in the ON clause are not quoted. Systematically quoting aliases even in FilteredRelation is tracked in https://code.djangoproject.com/ticket/36795.
1 parent 69065ca commit 005d60d

File tree

3 files changed

+26
-3
lines changed

3 files changed

+26
-3
lines changed

django/db/models/sql/query.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1720,6 +1720,11 @@ def _add_q(
17201720
return target_clause, needed_inner
17211721

17221722
def add_filtered_relation(self, filtered_relation, alias):
1723+
if "." in alias:
1724+
raise ValueError(
1725+
"FilteredRelation doesn't support aliases with periods "
1726+
"(got %r)." % alias
1727+
)
17231728
self.check_alias(alias)
17241729
filtered_relation.alias = alias
17251730
relation_lookup_parts, relation_field_parts, _ = self.solve_lookup_type(

tests/filtered_relation/tests.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,19 @@ def test_internal_queryset_alias_mapping(self):
216216
str(queryset.query),
217217
)
218218

219+
def test_period_forbidden(self):
220+
msg = (
221+
"FilteredRelation doesn't support aliases with periods (got 'book.alice')."
222+
)
223+
with self.assertRaisesMessage(ValueError, msg):
224+
Author.objects.annotate(
225+
**{
226+
"book.alice": FilteredRelation(
227+
"book", condition=Q(book__title__iexact="poem by alice")
228+
)
229+
}
230+
)
231+
219232
def test_multiple(self):
220233
qs = (
221234
Author.objects.annotate(

tests/ordering/tests.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
When,
1919
)
2020
from django.db.models.functions import Length, Upper
21-
from django.db.utils import DatabaseError
2221
from django.test import TestCase
2322

2423
from .models import (
@@ -411,13 +410,19 @@ def test_alias_with_period_shadows_table_name(self):
411410
self.assertNotEqual(qs[0].headline, "Backdated")
412411

413412
relation = FilteredRelation("author")
414-
qs2 = Article.objects.annotate(**{crafted: relation}).order_by(crafted)
415-
with self.assertRaises(DatabaseError):
413+
msg = (
414+
"FilteredRelation doesn't support aliases with periods "
415+
"(got 'ordering_article.pub_date')."
416+
)
417+
with self.assertRaisesMessage(ValueError, msg):
418+
qs2 = Article.objects.annotate(**{crafted: relation}).order_by(crafted)
416419
# Before, unlike F(), which causes ordering expressions to be
417420
# replaced by ordinals like n in ORDER BY n, these were ordered by
418421
# pub_date instead of author.
419422
# The Article model orders by -pk, so sorting on author will place
420423
# first any article by author2 instead of the backdated one.
424+
# This assertion is reachable if FilteredRelation.__init__() starts
425+
# supporting periods in aliases in the future.
421426
self.assertNotEqual(qs2[0].headline, "Backdated")
422427

423428
def test_order_by_pk(self):

0 commit comments

Comments
 (0)