Test d'intrusion Django : Déni de Service, ORM et Sécurité des Applications Web
Django est le framework Python web le plus éprouvé, avec une philosophie « batteries included » qui inclut un ORM, un système d'authentification, une protection CSRF native et un admin back-office. Malgré ces protections intégrées, les applications Django en production présentent régulièrement des vulnérabilités significatives. CVE-2024-45230 a démontré que le filtre de template strip_tags pouvait être exploité pour un déni de service via des entrées HTML spécialement construites. CVE-2023-43665 a montré le même problème avec truncatechars_html. Ces CVE illustrent qu'even les fonctionnalités apparemment anodines de Django peuvent constituer des vecteurs d'attaque lorsqu'elles traitent des entrées utilisateur non validées. Matproof examine vos applications Django de manière exhaustive pour toutes les vulnérabilités connues de ce framework.
Pourquoi les applications Django nécessitent des tests de sécurité spécialisés
Django fournit d'excellentes protections par défaut contre de nombreuses vulnérabilités web classiques — CSRF, XSS via l'échappement automatique des templates, injection SQL via l'ORM. Mais cette sécurité apparente peut conduire à un excès de confiance. L'ORM Django ne protège pas contre les requêtes brutes mal construites, les lookups de champs dynamiques (field__lookup) avec des entrées utilisateur non validées, ou la divulgation de données via des sérialiseurs trop permissifs. L'admin Django, activé par défaut, est une cible privilégiée si son URL n'est pas personnalisée. Les applications Django REST Framework (DRF) — la couche d'API la plus courante pour Django — introduisent leurs propres surfaces d'attaque via les permissions, sérialiseurs et filtres.
- CVE-2024-45230 (déni de service via django.utils.html.strip_tags) : le filtre strip_tags, couramment utilisé dans les applications Django pour nettoyer du contenu HTML avant affichage, était vulnérable à un déni de service via des entrées HTML spécialement construites contenant des attributs de très grande taille. Un attaquant pouvait envoyer un contenu HTML malformé vers tout endpoint Django utilisant ce filtre, provoquant une consommation CPU excessive.
- CVE-2024-39614 (vulnérabilité Django dans le traitement des requêtes) : cette CVE dans Django affectait le traitement de certains types de requêtes, permettant potentiellement des comportements inattendus dans la gestion des sessions ou l'authentification selon la configuration. Les applications utilisant des versions affectées et des configurations non standard étaient exposées.
- CVE-2023-43665 (déni de service via truncatechars_html dans les templates Django) : similaire à CVE-2024-45230, le filtre de template truncatechars_html était vulnérable à un DoS via des entrées HTML malformées. Ce filtre est largement utilisé dans les applications Django gérant du contenu utilisateur (blogs, forums, CMS Django). La mise à jour vers Django 4.2.7+ ou 3.2.23+ résolvait cette vulnérabilité.
- Injection via les lookups d'ORM dynamiques : Django ORM supporte des lookups dynamiques (Model.objects.filter(**user_input)) souvent utilisés pour construire des filtres flexibles. Si les clés du dictionnaire proviennent directement de l'entrée utilisateur, un attaquant peut modifier le lookup type (ex. ajouter __icontains, __in, ou des lookups cross-relation) pour extraire des données non autorisées ou effectuer des requêtes non prévues.
- Exposition de l'interface d'administration Django (/admin) : l'URL /admin est connue de tous les attaquants automatisés. Si elle n'est pas protégée par une URL personnalisée, un accès IP-restrictif ou une double authentification, elle constitue une cible permanente. Les vulnérabilités dans l'admin Django ou ses plugins (import-export, summernote) ont historiquement été critiques.
- Django REST Framework — permissions et sérialiseurs : les APIs DRF avec IsAuthenticated seul ne protègent pas contre l'accès aux ressources d'autres utilisateurs (IDOR). Les sérialiseurs acceptant tous les champs sans restriction (ModelSerializer sans exclude) peuvent conduire à un mass-assignment. Les filtres Django-Filter acceptant des champs dynamiques peuvent exposer des données non autorisées.
- Vulnérabilités dans les packages Django tiers : l'écosystème PyPI pour Django (django-allauth, celery, django-storages, djangorestframework) est vaste ; des paquets populaires sont régulièrement affectés par des CVE. Un audit de dépendances révèle fréquemment des versions vulnérables dans les applications Django établies.
Ce qui est examiné lors d'un test d'intrusion Django
- Audit des dépendances Django et des packages PyPI : scan de tous les packages Django installés contre NVD et Django Security Advisories ; vérification des versions de Django, djangorestframework, celery, django-allauth, django-storages et autres packages courants.
- Test de déni de service sur les filtres de templates : envoi de données HTML malformées vers tous les endpoints Django utilisant strip_tags, truncatechars_html, linebreaks ou d'autres filtres de template traitant des entrées utilisateur ; mesure de la consommation CPU et du temps de réponse.
- Sécurité de l'interface d'administration Django : test de l'accessibilité de /admin et des URLs d'administration alternatives ; test de force brute sur les identifiants d'administration ; vérification des plugins d'admin installés pour les CVE connus ; audit des permissions des utilisateurs admin.
- ORM Django et prévention des injections : test des vues utilisant .filter(**kwargs) avec des entrées utilisateur ; test des requêtes brutes (raw(), extra(), connection.cursor()) pour les injections SQL ; vérification des lookups cross-relation pouvant exposer des données d'autres tables.
- Sécurité Django REST Framework : audit des classes de permission (IsAuthenticated, IsOwner, personnalisées) sur tous les ViewSets et APIViews ; test IDOR sur les endpoints de ressources scopées ; vérification des sérialiseurs pour le mass-assignment et l'exposition de champs sensibles.
- Protection CSRF et authentification des sessions : vérification de la protection CSRF sur tous les endpoints mutants (vue-par-vue, pas uniquement globale) ; test de la gestion des sessions (flags de cookies, durée de vie, invalidation à la déconnexion) ; test de fixation de session.
- Téléchargement de fichiers et gestion des médias : test des vues de téléchargement pour les restrictions de type MIME, la validation du contenu réel, le path traversal dans les noms de fichiers ; vérification de la configuration django-storages (S3/Azure) pour l'exposition publique non intentionnelle.
- Sécurité des settings Django en production : vérification de SECRET_KEY (longueur, entropie, non exposé), DEBUG=False, ALLOWED_HOSTS configuré, SECURE_HSTS_SECONDS, SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE et autres paramètres de sécurité de la checklist Django.
- Test XSS dans les templates Django : bien que Django échappe les variables par défaut, les templates utilisant |safe, mark_safe() ou format_html() sans validation adéquate créent des vecteurs XSS ; test systématique des points d'injection de contenu non échappé.
- Celery et gestion des tâches asynchrones : si Celery est utilisé, test de la sécurité de la connexion au broker (Redis/RabbitMQ), de la sérialisation des tâches (risque de désérialisation si pickle est utilisé), et de l'accès aux résultats de tâches via Flower ou l'interface d'administration Celery.
Exemple de finding
Déni de service via le filtre strip_tags Django (CVE-2024-45230)
L'application Django utilise le filtre strip_tags dans plusieurs templates pour nettoyer les commentaires et descriptions soumis par les utilisateurs avant affichage (ex. {{ user_comment|strip_tags }}). La version Django 4.2.5 installée est affectée par CVE-2024-45230. Lors du test, l'envoi d'un commentaire contenant un attribut HTML de 100 000 caractères répétés (construction spécifique) dans l'endpoint POST /api/comments/ a provoqué une utilisation CPU de 100 % sur le processus Gunicorn pendant 38 secondes, bloquant le traitement de toutes les autres requêtes. L'endpoint est accessible à tout utilisateur authentifié (rôle minimum requis : utilisateur standard).
Correction : Mettre à jour Django vers la version 4.2.7+ ou 5.0.1+ (corrige CVE-2024-45230 et CVE-2023-43665). Implémenter une validation de longueur maximale sur tous les champs de contenu utilisateur avant le passage aux filtres de template (ex. valider max_length=10000 dans le sérialiseur DRF). Envisager l'utilisation d'une bibliothèque de sanitisation HTML dédiée (bleach, nh3) qui offre plus de contrôle sur le parsing HTML que les filtres de template Django. Implémenter un rate-limiting sur les endpoints acceptant du contenu utilisateur. Référence : Django Security Releases, OWASP A05:2021.
Référence : CVE-2024-45230 · CVE-2023-43665 (truncatechars_html DoS) · CVE-2024-39614 · OWASP A05:2021 Security Misconfiguration · CWE-400 Uncontrolled Resource Consumption
Pentest Django : comparaison des options
| — | Scan gratuit | Matproof Sentinel | Consultance classique |
|---|---|---|---|
| Moteur de scan automatisé | ✓ (aperçu 3 min) | ✓ Scan complet | ✗ Manuel uniquement |
| Couverture OWASP Top 10 | Partielle | ✓ Complète | ✓ Complète |
| Preuve d'exploitation | ✗ | ✓ Par finding | ✓ Par finding |
| Mapping réglementaire (DORA/NIS2/ISO 27001) | ✗ | ✓ Automatisé | ✓ Manuel |
| Rapport PDF prêt pour l'audit | ✗ | ✓ Instantané | ✓ Livraison 2–4 semaines |
| Scans continus / récurrents | ✗ | ✓ Par déploiement | ✗ Engagement annuel |
| Délai avant premier résultat | ~3 min | ~30 min scan complet | 2–4 semaines |
| Prix | €0 | À partir de €149 | €8 000–€25 000 |
| Revue de code source (SAST) | ✗ | ✓ Plan Growth | ✓ Périmètre défini |
| Tests API (REST/GraphQL) | ✗ | ✓ Automatisé | ✓ Manuel |
Offres de pentest Django
- 1 scan pentest complet
- Résultats priorisés par IA avec CVSS 3.1
- Proof-of-exploit pour chaque finding
- Rapport PDF (prêt pour l'audit)
- Mapping réglementaire (DORA, NIS2, ISO 27001)
- Scans illimités (jusqu'à 3 domaines)
- Surveillance continue
- Intégration CI/CD (GitHub, GitLab)
- Tous les mappings réglementaires
- Support prioritaire
- Scans + domaines illimités
- Tests authentifiés / White-Box
- Tests d'API et d'infrastructure cloud
- Account manager sécurité dédié
- SLA réponse 24h
Questions fréquentes sur le test d'intrusion Django
Django est connu pour sa sécurité intégrée — pourquoi est-ce quand même nécessaire de faire un pentest ?
Django fournit d'excellentes protections par défaut (CSRF, XSS, injection SQL via ORM, clickjacking) qui réduisent significativement la surface d'attaque par rapport à un framework minimal. Cependant, ces protections ne couvrent pas : les vulnérabilités de logique métier spécifiques à votre application, les erreurs d'implémentation (mark_safe() mal utilisé, requêtes ORM dynamiques non filtrées, IDOR dans les APIs DRF), les CVE dans les dépendances tierces (django-allauth, celery), et les misconfiguration de production (SECRET_KEY exposé, DEBUG=True, ALLOWED_HOSTS trop permissif). Un pentest Django spécialisé couvre ces angles que la sécurité intégrée du framework ne peut pas adresser.
Comment fonctionnent les CVE de déni de service Django (CVE-2024-45230 et CVE-2023-43665) ?
Ces deux CVE affectent des filtres de template Django qui utilisent des expressions régulières pour parser du HTML. La bibliothèque re de Python (et son moteur regex) peut souffrir de « catastrophic backtracking » (ReDoS) lorsqu'elle traite certains patterns d'entrée sur des chaînes spécialement construites. CVE-2024-45230 affecte strip_tags et CVE-2023-43665 affecte truncatechars_html. Un attaquant envoie une chaîne HTML avec des attributs ou des structures répétitives conçues pour maximiser les étapes de backtracking, résultant en une consommation CPU exponentielle. Django a corrigé ces vulnérabilités en remplaçant les regex par des parseurs HTML plus robustes.
L'ORM Django est-il complètement immunisé contre les injections SQL ?
L'ORM Django protège contre les injections SQL classiques dans les requêtes construites via l'interface ORM standard (filter(), get(), create()). Les vecteurs d'injection SQL dans Django incluent : (1) requêtes brutes avec raw() ou cursor.execute() avec des paramètres concaténés ; (2) extra(where=['condition %s' % user_input]) — deprecated mais encore présent dans le vieux code ; (3) .filter(**{user_input: value}) où les clés du dictionnaire proviennent de l'utilisateur permettant des lookups inattendus ; (4) RawSQL() et Func() avec des entrées non paramétrées. Matproof teste spécifiquement ces vecteurs dans le code Django.
Comment sécuriser l'interface d'administration Django ?
Mesures essentielles pour la sécurité de l'admin Django : (1) changer l'URL d'admin (path('secret-path/', admin.site.urls) au lieu de 'admin/') pour réduire les attaques automatisées ; (2) activer la 2FA pour tous les comptes admin (django-two-factor-auth ou django-otp) ; (3) restreindre l'accès par IP allowlist via Nginx/middleware si vous opérez depuis des IPs fixes ; (4) activer ADMIN_SITE.has_permission pour vérifier des conditions supplémentaires ; (5) auditer régulièrement les actions d'admin via django.contrib.admin LogEntry ; (6) supprimer l'accès admin de l'environnement de production pour les comptes de test.
Django REST Framework est-il sécurisé par défaut pour les APIs publiques ?
DRF par défaut (DEFAULT_AUTHENTICATION_CLASSES = SessionAuthentication et BasicAuthentication, DEFAULT_PERMISSION_CLASSES = AllowAny dans les anciennes versions) est permissif. Pour les APIs de production : configurer DEFAULT_PERMISSION_CLASSES = [IsAuthenticated] globalement et surcharger explicitement pour les endpoints publics ; utiliser JWTAuthentication via djangorestframework-simplejwt avec une configuration sécurisée ; implémenter des permissions d'objet (has_object_permission) sur tous les ViewSets manipulant des ressources scopées par utilisateur ; définir des sérialiseurs stricts avec des champs explicitement listés (pas de fields = '__all__').
Comment Django gère-t-il la protection CSRF et dans quels cas peut-elle être contournée ?
La protection CSRF Django est activée par défaut via le middleware CsrfViewMiddleware pour toutes les requêtes POST/PUT/PATCH/DELETE. Elle peut être contournée ou mal configurée dans les cas suivants : (1) utilisation de @csrf_exempt sur des endpoints qui devraient être protégés ; (2) APIs DRF utilisant TokenAuthentication ou JWTAuthentication — DRF désactive la vérification CSRF pour ces méthodes d'authentification (comportement intentionnel mais potentiellement dangereux si la session est aussi utilisée) ; (3) erreur de configuration du domaine CSRF_TRUSTED_ORIGINS avec un wildcard trop large ; (4) endpoints AJAX sans le cookie csrftoken ou l'en-tête X-CSRFToken correctement configurés.
Quelle est la checklist de configuration Django recommandée pour la production ?
Checklist Django production (manage.py check --deploy) : DEBUG=False, SECRET_KEY unique et entropie élevée (min. 50 chars), ALLOWED_HOSTS sans wildcard, SECURE_HSTS_SECONDS=31536000 (et SECURE_HSTS_INCLUDE_SUBDOMAINS), SESSION_COOKIE_SECURE=True, CSRF_COOKIE_SECURE=True, X_FRAME_OPTIONS='DENY', SECURE_CONTENT_TYPE_NOSNIFF=True, SECURE_BROWSER_XSS_FILTER=True (Django < 4.0), DATABASES avec un utilisateur de base de données aux privilèges minimaux, LOG configuration excluant les données sensibles des logs, et désactivation de l'interface /admin si non nécessaire en production.
À quelle fréquence doit-on faire un pentest d'une application Django en production ?
Recommandation : pentest complet annuel pour les applications Django avec des données utilisateurs ou des transactions, plus un test ciblé après chaque migration vers une nouvelle version majeure de Django (passage de Django 3.x à 4.x ou 5.x), après l'ajout de DRF ou de nouveaux endpoints API sensibles, ou après un changement d'architecture (ajout de Celery, migration cloud). La surveillance continue via Matproof Sentinel est particulièrement précieuse pour suivre les CVE Django — l'équipe de sécurité Django publie des correctifs de sécurité régulièrement pour les versions LTS supportées.
Approfondir — articles de blog associés
Démarrez votre test d'intrusion Django maintenant
Vérifiez en quelques minutes si votre application Django est exposée à des vulnérabilités de déni de service dans les templates, des failles ORM ou des misconfiguration de production. Rapport audit-ready en français, aucune installation requise.
Démarrer le pentest Django