diff options
| -rw-r--r-- | django/db/models/sql/compiler.py | 2 | ||||
| -rw-r--r-- | docs/releases/4.2.28.txt | 10 | ||||
| -rw-r--r-- | docs/releases/5.2.11.txt | 10 | ||||
| -rw-r--r-- | tests/ordering/tests.py | 25 |
4 files changed, 46 insertions, 1 deletions
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 4292243c71..7dbdec3635 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -433,7 +433,7 @@ class SQLCompiler: yield OrderBy(expr, descending=descending), False continue - if "." in field: + if "." in field and field in self.query.extra_order_by: # This came in through an extra(order_by=...) addition. Pass it # on verbatim. table, col = col.split(".", 1) diff --git a/docs/releases/4.2.28.txt b/docs/releases/4.2.28.txt index 473e44f577..1d81095b3e 100644 --- a/docs/releases/4.2.28.txt +++ b/docs/releases/4.2.28.txt @@ -66,3 +66,13 @@ expansion, as the ``**kwargs`` passed to :meth:`.QuerySet.annotate`, This issue has severity "high" according to the :ref:`Django security policy <security-disclosure>`. + +CVE-2026-1312: Potential SQL injection via ``QuerySet.order_by`` and ``FilteredRelation`` +========================================================================================= + +:meth:`.QuerySet.order_by` was subject to SQL injection in column aliases +containing periods when the same alias was, using a suitably crafted +dictionary, with dictionary expansion, used in :class:`.FilteredRelation`. + +This issue has severity "high" according to the :ref:`Django security policy +<security-disclosure>`. diff --git a/docs/releases/5.2.11.txt b/docs/releases/5.2.11.txt index fa14a88c0a..76efc4aa8d 100644 --- a/docs/releases/5.2.11.txt +++ b/docs/releases/5.2.11.txt @@ -66,3 +66,13 @@ expansion, as the ``**kwargs`` passed to :meth:`.QuerySet.annotate`, This issue has severity "high" according to the :ref:`Django security policy <security-disclosure>`. + +CVE-2026-1312: Potential SQL injection via ``QuerySet.order_by`` and ``FilteredRelation`` +========================================================================================= + +:meth:`.QuerySet.order_by` was subject to SQL injection in column aliases +containing periods when the same alias was, using a suitably crafted +dictionary, with dictionary expansion, used in :class:`.FilteredRelation`. + +This issue has severity "high" according to the :ref:`Django security policy +<security-disclosure>`. diff --git a/tests/ordering/tests.py b/tests/ordering/tests.py index b29404ed77..530a27920e 100644 --- a/tests/ordering/tests.py +++ b/tests/ordering/tests.py @@ -7,6 +7,7 @@ from django.db.models import ( Count, DateTimeField, F, + FilteredRelation, Max, OrderBy, OuterRef, @@ -14,6 +15,7 @@ from django.db.models import ( Value, ) from django.db.models.functions import Length, Upper +from django.db.utils import DatabaseError from django.test import TestCase from .models import ( @@ -392,6 +394,29 @@ class OrderingTests(TestCase): attrgetter("headline"), ) + def test_alias_with_period_shadows_table_name(self): + """ + Aliases with periods are not confused for table names from extra(). + """ + Article.objects.update(author=self.author_2) + Article.objects.create( + headline="Backdated", pub_date=datetime(1900, 1, 1), author=self.author_1 + ) + crafted = "ordering_article.pub_date" + + qs = Article.objects.annotate(**{crafted: F("author")}).order_by("-" + crafted) + self.assertNotEqual(qs[0].headline, "Backdated") + + relation = FilteredRelation("author") + qs2 = Article.objects.annotate(**{crafted: relation}).order_by(crafted) + with self.assertRaises(DatabaseError): + # Before, unlike F(), which causes ordering expressions to be + # replaced by ordinals like n in ORDER BY n, these were ordered by + # pub_date instead of author. + # The Article model orders by -pk, so sorting on author will place + # first any article by author2 instead of the backdated one. + self.assertNotEqual(qs2[0].headline, "Backdated") + def test_order_by_pk(self): """ 'pk' works as an ordering option in Meta. |
