Introduction
Attackers who can control dictionary keys passed to certain Django QuerySet methods may be able to execute arbitrary SQL on MySQL or MariaDB backends. This vulnerability affects a significant portion of Django deployments, especially those using dynamic query construction with user input. The Django web framework, maintained by the Django Software Foundation, is a cornerstone of Python web development and powers thousands of sites and applications across industries. Its ORM layer is trusted for strong SQL injection protections, making this vulnerability particularly notable for security teams and developers.
Technical Information
CVE-2025-59681 targets Django's QuerySet.annotate(), alias(), aggregate(), and extra() methods when used with MySQL or MariaDB databases. The vulnerability arises when a dictionary is passed as **kwargs to these methods. In Django's ORM, these dictionary keys are used directly as column aliases in the generated SQL. On MySQL and MariaDB, the handling of these aliases allows for SQL injection if the keys are not properly sanitized.
The root cause is the lack of validation on dictionary keys used as column aliases. When user-controlled input is allowed to influence these keys, an attacker can craft a dictionary where the key contains malicious SQL. This key is then inserted into the SQL query as an alias, bypassing Django's usual parameterization and escaping mechanisms. The vulnerability is specific to MySQL and MariaDB due to their SQL syntax and how they parse column aliases.
For example, if an application constructs a dictionary from user input and passes it as **kwargs to annotate(), an attacker could supply a key like malicious_alias; DROP TABLE users; --
which would be inserted into the SQL query. This could allow for execution of arbitrary SQL statements, data exfiltration, or destruction, depending on the database user's privileges. The vulnerability does not affect other backends such as PostgreSQL or SQLite.
No public code snippets or PoC are available as of this writing, and exploitation requires that user input is used directly as dictionary keys in these methods.
Patch Information
The Django team has released versions 5.2.7, 5.1.13, and 4.2.25 to address two security vulnerabilities:
-
CVE-2025-59681: This high-severity issue involved potential SQL injection vulnerabilities in the
QuerySet.annotate()
,alias()
,aggregate()
, andextra()
methods on MySQL and MariaDB databases. The vulnerability allowed SQL injection through column aliases when a specially crafted dictionary was passed as**kwargs
to these methods.Patch Details:
- The patch introduces validation to ensure that column aliases provided via
**kwargs
are properly sanitized, preventing malicious input from being executed as SQL code.
- The patch introduces validation to ensure that column aliases provided via
-
CVE-2025-59682: This low-severity issue pertained to a partial directory-traversal vulnerability in the
django.utils.archive.extract()
function. The function, used bystartapp --template
andstartproject --template
, allowed partial directory traversal via an archive containing file paths with a common prefix matching the target directory.Patch Details:
- The patch enhances the
extract()
function to validate and sanitize file paths within archives, ensuring that extracted files do not escape the intended target directory.
- The patch enhances the
These patches have been applied to Django's main, 6.0 (currently at alpha status), 5.2, 5.1, and 4.2 branches. Users are strongly encouraged to upgrade to the latest versions to mitigate these vulnerabilities.
Patch source: https://www.djangoproject.com/weblog/2025/oct/01/security-releases/
Affected Systems and Versions
- Django 4.2 before 4.2.25
- Django 5.1 before 5.1.13
- Django 5.2 before 5.2.7
Only installations using MySQL or MariaDB as the database backend are affected. Other database backends are not vulnerable to this issue.
Vendor Security History
Django has a strong security track record, but 2025 has seen several notable vulnerabilities in its ORM layer. CVE-2025-57833, disclosed in September 2025, affected the FilteredRelation feature and also allowed SQL injection under certain conditions. The Django team has consistently responded quickly to such disclosures, issuing coordinated patches and advisories for all supported versions. The project maintains a transparent and mature security process, with clear communication and rapid remediation.