CVE-2024-42005 in Django: a hidden SQL injection behind JSONField
Published on 2026-10-27 by frfrand
How a SQL injection flaw arose in Django QuerySet, which versions it affected, when there is exposure, and what to correct.

Does Django's ORM prevent all SQL injections?
An ORM helps a lot, but it does not make any external input safe. CVE-2024-42005, fixed by Django in August 2024, shows a concrete case: certain calls to QuerySet.values() and values_list() on models with JSONField could result in SQL injection when maliciously crafted JSON keys were used as column arguments.
What does JSONField do?
It allows storing and querying data with JSON structure in a column. It is useful for configurations and variable attributes; for example, a product profile with different characteristics. The problem appears when a field name or a JSON key is used as part of the query structure, instead of treating it solely as validated data.
Who detected it?
Django documented the vulnerability in its official notes on August 6, 2024. To investigate this type of defect, SQL generation from ORM methods is inspected and special identifiers, aliases, and unexpected inputs are tested. If you need to know the exact authorship of the finding, consult the official record; it is not advisable to invent research credits.
How could it be exploited?
Imagine an endpoint that lets the user choose fields from a response and passes those names directly to values(). If the model uses JSONField and the names can manipulate SQL aliases, the user could influence the query. It is not triggered simply by having Django and PostgreSQL installed: the relevant functions and input flow are required.
Why does it matter so much if Django usually parameterizes?
Parameterized queries protect values, but identifiers and aliases may require another type of validation. Trusting in a safe function for values when you are actually building SQL structure is a common mistake. The impact depends on the database user's permissions and on what operations the affected query allows.
Which versions were fixed?
Django's release notes point to fixes in 5.0.8 and 4.2.15. These are reference versions from the 2024 bulletin. For 2026, I chose a still-maintained branch and review its advisories; do not freeze an application on an old release.
How to check if your Django project is exposed?
Look for uses of values(), values_list() and models with JSONField. Investigate especially endpoints that accept field names, orderings or dynamic selections from the API. Confirm that there is an allowlist of names defined by the developer instead of passing client strings to the query. Tests must cover unusual inputs and SQL role permissions.
How to fix it?
Update Django; validate the fields a client can request; use minimal permissions in the database; add regression tests and review helper functions that generate dynamic queries. If abuse is suspected, keep logs and analyze the operations actually executed before determining scope.
Quick questions
Does it affect all models? No: the documented scenario involves models with JSONField and specific arguments.
Is manually escaping the string enough? No. It is safer to validate a closed set of identifiers and update the framework.
Does having DRF change anything? It depends on how the view transforms user parameters into QuerySet operations.
Sources: Django 5.0.8 Notes · Django 4.2.15 Notes · CVE Record.
Where to follow CVEs and receive guidance?
On ArduMaker CVE and support we publish updates and centralize inquiries about vulnerabilities, starting with WordPress and its related technologies. If your case involves another runtime or a database, specify component, version, operating system, and service exposure to contextualize it. The notice of a CVE does not prove that your server is compromised: evaluation requires inventory, configuration, and evidence.
Editorial note — October 2026: these patched versions are the milestones of the original notice. When updating today, choose a branch with active support and verify the manufacturer's current announcement.
Practical example: choosing dynamic Django fields without trusting the user
Situation: a products API supports ?campo=id&campo=nombre and transforms each parameter directly into QuerySet.values() arguments. If those names come from users, they must be validated, especially when combined with JSONField.
Simplified example with an allowlist:
CAMPOS_PERMITIDOS = {"id", "nombre", "estado"}
solicitados = request.GET.getlist("campo")
if not solicitados or any(c not in CAMPOS_PERMITIDOS for c in solicitados):
return JsonResponse({"error": "Campo no permitido"}, status=400)
filas = list(Producto.objects.values(*solicitados))
return JsonResponse({"resultados": filas})
Before: passing client-sent names directly to the ORM without control. After: update Django, validate identifiers against a closed list, and use a SQL role without administrative privileges.
Important: the example illustrates an application-level defense; the official fix for CVE-2024-42005 is still necessary. Also test what happens with empty requests, repeated fields, and arbitrary JSON keys.
