diff options
| -rw-r--r-- | django/db/backends/postgresql/compiler.py | 11 | ||||
| -rw-r--r-- | docs/releases/4.2.27.txt | 8 | ||||
| -rw-r--r-- | docs/releases/5.1.15.txt | 8 | ||||
| -rw-r--r-- | docs/releases/5.2.9.txt | 8 | ||||
| -rw-r--r-- | tests/annotations/tests.py | 11 |
5 files changed, 45 insertions, 1 deletions
diff --git a/django/db/backends/postgresql/compiler.py b/django/db/backends/postgresql/compiler.py index dc2db148ae..38b61c4898 100644 --- a/django/db/backends/postgresql/compiler.py +++ b/django/db/backends/postgresql/compiler.py @@ -1,6 +1,6 @@ from django.db.models.sql.compiler import ( SQLAggregateCompiler, - SQLCompiler, + SQLCompiler as BaseSQLCompiler, SQLDeleteCompiler, ) from django.db.models.sql.compiler import SQLInsertCompiler as BaseSQLInsertCompiler @@ -25,6 +25,15 @@ class InsertUnnest(list): return "UNNEST(%s)" % ", ".join(self) +class SQLCompiler(BaseSQLCompiler): + def quote_name_unless_alias(self, name): + if "$" in name: + raise ValueError( + "Dollar signs are not permitted in column aliases on PostgreSQL." + ) + return super().quote_name_unless_alias(name) + + class SQLInsertCompiler(BaseSQLInsertCompiler): def assemble_as_sql(self, fields, value_rows): # Specialize bulk-insertion of literal values through UNNEST to diff --git a/docs/releases/4.2.27.txt b/docs/releases/4.2.27.txt index 7ffa5fa458..e95dc63f74 100644 --- a/docs/releases/4.2.27.txt +++ b/docs/releases/4.2.27.txt @@ -7,6 +7,14 @@ Django 4.2.27 release notes Django 4.2.27 fixes one security issue with severity "high", one security issue with severity "moderate", and one bug in 4.2.26. +CVE-2025-13372: Potential SQL injection in ``FilteredRelation`` column aliases on PostgreSQL +============================================================================================ + +: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` on +PostgreSQL. + Bugfixes ======== diff --git a/docs/releases/5.1.15.txt b/docs/releases/5.1.15.txt index 2c4e029590..f55623ea96 100644 --- a/docs/releases/5.1.15.txt +++ b/docs/releases/5.1.15.txt @@ -7,6 +7,14 @@ Django 5.1.15 release notes Django 5.1.15 fixes one security issue with severity "high", one security issue with severity "moderate", and one bug in 5.1.14. +CVE-2025-13372: Potential SQL injection in ``FilteredRelation`` column aliases on PostgreSQL +============================================================================================ + +: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` on +PostgreSQL. + Bugfixes ======== diff --git a/docs/releases/5.2.9.txt b/docs/releases/5.2.9.txt index 9dfcc392a0..08c298999a 100644 --- a/docs/releases/5.2.9.txt +++ b/docs/releases/5.2.9.txt @@ -7,6 +7,14 @@ Django 5.2.9 release notes Django 5.2.9 fixes one security issue with severity "high", one security issue with severity "moderate", and several bugs in 5.2.8. +CVE-2025-13372: Potential SQL injection in ``FilteredRelation`` column aliases on PostgreSQL +============================================================================================ + +: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` on +PostgreSQL. + Bugfixes ======== diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index 7a12121224..78e5408d0f 100644 --- a/tests/annotations/tests.py +++ b/tests/annotations/tests.py @@ -1507,3 +1507,14 @@ class AliasTests(TestCase): ) with self.assertRaisesMessage(ValueError, msg): Book.objects.alias(**{crafted_alias: FilteredRelation("authors")}) + + def test_alias_filtered_relation_sql_injection_dollar_sign(self): + qs = Book.objects.alias( + **{"crafted_alia$": FilteredRelation("authors")} + ).values("name", "crafted_alia$") + if connection.vendor == "postgresql": + msg = "Dollar signs are not permitted in column aliases on PostgreSQL." + with self.assertRaisesMessage(ValueError, msg): + list(qs) + else: + self.assertEqual(qs.first()["name"], self.b1.name) |
