summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/backends/postgresql/compiler.py11
-rw-r--r--docs/releases/4.2.27.txt8
-rw-r--r--docs/releases/5.1.15.txt8
-rw-r--r--docs/releases/5.2.9.txt8
-rw-r--r--tests/annotations/tests.py11
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)