Skip to content

Commit 6703f36

Browse files
jacobtylerwallsnessita
authored andcommitted
[5.2.x] Fixed CVE-2025-64459 -- Prevented SQL injections in Q/QuerySet via the _connector kwarg.
Thanks cyberstan for the report, Sarah Boyce, Adam Johnson, Simon Charette, and Jake Howard for the reviews. Backport of c880530 from main.
1 parent 4f5d904 commit 6703f36

File tree

5 files changed

+30
-0
lines changed

5 files changed

+30
-0
lines changed

django/db/models/query_utils.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,12 @@ class Q(tree.Node):
4848
XOR = "XOR"
4949
default = AND
5050
conditional = True
51+
connectors = (None, AND, OR, XOR)
5152

5253
def __init__(self, *args, _connector=None, _negated=False, **kwargs):
54+
if _connector not in self.connectors:
55+
connector_reprs = ", ".join(f"{conn!r}" for conn in self.connectors[1:])
56+
raise ValueError(f"_connector must be one of {connector_reprs}, or None.")
5357
super().__init__(
5458
children=[*args, *sorted(kwargs.items())],
5559
connector=_connector,

docs/releases/4.2.26.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`,
1616
:func:`redirect() <django.shortcuts.redirect>` were subject to a potential
1717
denial-of-service attack via certain inputs with a very large number of Unicode
1818
characters (follow up to :cve:`2025-27556`).
19+
20+
CVE-2025-64459: Potential SQL injection via ``_connector`` keyword argument
21+
===========================================================================
22+
23+
:meth:`.QuerySet.filter`, :meth:`~.QuerySet.exclude`, :meth:`~.QuerySet.get`,
24+
and :class:`~.Q` were subject to SQL injection using a suitably crafted
25+
dictionary, with dictionary expansion, as the ``_connector`` argument.

docs/releases/5.1.14.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`,
1616
:func:`redirect() <django.shortcuts.redirect>` were subject to a potential
1717
denial-of-service attack via certain inputs with a very large number of Unicode
1818
characters (follow up to :cve:`2025-27556`).
19+
20+
CVE-2025-64459: Potential SQL injection via ``_connector`` keyword argument
21+
===========================================================================
22+
23+
:meth:`.QuerySet.filter`, :meth:`~.QuerySet.exclude`, :meth:`~.QuerySet.get`,
24+
and :class:`~.Q` were subject to SQL injection using a suitably crafted
25+
dictionary, with dictionary expansion, as the ``_connector`` argument.

docs/releases/5.2.8.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ Windows. As a consequence, :class:`~django.http.HttpResponseRedirect`,
1818
denial-of-service attack via certain inputs with a very large number of Unicode
1919
characters (follow up to :cve:`2025-27556`).
2020

21+
CVE-2025-64459: Potential SQL injection via ``_connector`` keyword argument
22+
===========================================================================
23+
24+
:meth:`.QuerySet.filter`, :meth:`~.QuerySet.exclude`, :meth:`~.QuerySet.get`,
25+
and :class:`~.Q` were subject to SQL injection using a suitably crafted
26+
dictionary, with dictionary expansion, as the ``_connector`` argument.
27+
2128
Bugfixes
2229
========
2330

tests/queries/test_q.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,11 @@ def test_create_helper(self):
272272
Q(*items, _connector=connector),
273273
)
274274

275+
def test_connector_validation(self):
276+
msg = f"_connector must be one of {Q.AND!r}, {Q.OR!r}, {Q.XOR!r}, or None."
277+
with self.assertRaisesMessage(ValueError, msg):
278+
Q(_connector="evil")
279+
275280
def test_referenced_base_fields(self):
276281
# Make sure Q.referenced_base_fields retrieves all base fields from
277282
# both filters and F expressions.

0 commit comments

Comments
 (0)