Chaque application s’exécute en tant que 4 conteneurs Docker avec répartition de charge derrière des pools upstream nginx, accessibles via le proxy inverse nginx sur la VM. Les sessions persistantes garantissent que les applications avec état (Juice Shop, DVWA, VAmPI, CSD Demo) sont acheminées de manière cohérente. Toutes les applications sont intentionnellement vulnérables et conçues pour les tests de sécurité.
Remplacez <ORIGIN> par http://<PUBLIC_IP> dans tous les exemples ci-dessous. Après le déploiement via Terraform, obtenez l’adresse IP avec terraform output -raw public_ip.
Chemin Application Méthode HTTP Réponse attendue /Page d’accueil GET 200 HTML avec liens vers toutes les applications /healthVérification d’état GET 200 JSON {"status":"healthy","component":"origin-server",...} /juice-shop/Juice Shop GET 200 HTML (Angular SPA, ~75 Ko) /juice-shop/rest/products/search?q=API Juice Shop GET 200 JSON {"status":"success","data":[...]} (36 produits) /dvwa/DVWA GET 302 redirection vers /dvwa/login.php /dvwa/login.phpConnexion DVWA GET 200 HTML formulaire de connexion /dvwa/setup.phpConfiguration DVWA GET 200 HTML (initialisation de la base de données au premier démarrage) /vampi/VAmPI GET 200 HTML (documentation API) /vampi/users/v1API VAmPI GET 200 JSON {"users":[...]} /vampi/users/v1/registerAPI VAmPI POST 200 JSON {"status":"success",...} /vampi/users/v1/loginAPI VAmPI POST 200 JSON {"auth_token":"...","status":"success"} /httpbin/gethttpbin GET 200 JSON avec les détails de la requête /httpbin/posthttpbin POST 200 JSON avec les données publiées /httpbin/headershttpbin GET 200 JSON {"headers":{...}} /httpbin/status/:codehttpbin GET Retourne le code de statut HTTP spécifié /whoami/whoami GET 200 texte brut avec le nom d’hôte, l’IP et tous les en-têtes /csd-demo/CSD Demo GET 200 HTML formulaire de paiement avec panneau d’attaque /csd-demo/dashboardVue attaquant CSD GET 200 HTML affichant les données exfiltrées /csd-demo/healthÉtat CSD GET 200 JSON {"status":"healthy","component":"csd-demo",...} /csd-demo/exfil/logJournal d’exfiltration CSD GET 200 tableau JSON des données capturées /dvga/DVGA GraphiQL GET 200 HTML (IDE GraphiQL) /dvga/graphqlAPI GraphQL DVGA POST 200 JSON réponse GraphQL /restaurant/RESTaurant GET 200 (redirige vers la documentation) /restaurant/docsSwagger RESTaurant GET 200 HTML (interface Swagger FastAPI) /restaurant/openapi.jsonOpenAPI RESTaurant GET 200 JSON spécification OpenAPI http://<PUBLIC_IP>:8888crAPI GET 200 HTML (SPA) http://<PUBLIC_IP>:8888/identity/api/auth/signupInscription crAPI POST 200 JSON http://<PUBLIC_IP>:8888/identity/api/auth/loginConnexion crAPI POST 200 JSON {"token":"..."}
Chemin /juice-shop/Image bkimminich/juice-shop:latestInstances 4 (ports 3001-3004), persistance via hash $cookie_token, cache proxy (TTL 60 s) Ressources 2 CPU / 1 Gio de RAM par instance Framework Node.js / Angular Projet owasp.org/www-project-juice-shop
OWASP Juice Shop est l’application web vulnérable la plus moderne et la plus activement maintenue. Elle couvre l’intégralité de l’OWASP Top 10 avec plus de 100 défis dans une application e-commerce réaliste.
Scénario Catégorie Vecteur d’attaque Contournement de connexion par injection SQL Pare-feu applicatif (WAF) ' OR 1=1-- dans le champ email de connexionXSS réfléchi Pare-feu applicatif (WAF), Défense côté client Injection de script via le paramètre de recherche XSS basé sur le DOM Défense côté client Charge utile dans le fragment d’URL Authentification compromise Pare-feu applicatif (WAF) Attaque par force brute, manipulation JWT Abus d’API Sécurité des API Accès non autorisé aux points de terminaison /api/ Exposition de données sensibles Sécurité des API Accès aux données utilisateur sans autorisation CSRF Pare-feu applicatif (WAF) Falsification de requête inter-sites sur les modifications de profil
curl -s " http://<PUBLIC_IP>/juice-shop/ " -o /dev/null -w " %{http_code} "
Chemin /dvwa/Image dvwa-fpm:latest personnalisée (php-fpm + nginx, construite à partir de ghcr.io/digininja/dvwa:latest)Instances 4 (ports 8101-8104), persistance via hash $cookie_PHPSESSID Ressources 0,5 CPU / 256 Mio de RAM par instance Base de données MariaDB 10.11 partagée (conteneur dvwa-db, 1 CPU / 768 Mio) Framework PHP 8 / php-fpm / MariaDB Identifiants admin / password
DVWA est la référence du secteur pour les tests de pare-feu applicatif (WAF). Il dispose de niveaux de sécurité ajustables (Faible, Moyen, Élevé, Impossible) qui ajoutent progressivement la validation des entrées et l’encodage des sorties.
Scénario Catégorie Niveau de sécurité Injection SQL Pare-feu applicatif (WAF) Faible : ' OR 1=1# trivial, Élevé : SQLi aveugle Injection de commandes Pare-feu applicatif (WAF) Faible : ; ls, Élevé : caractères filtrés Inclusion de fichiers Pare-feu applicatif (WAF) Faible : traversée de chemin directe, Élevé : assaini XSS (Réfléchi) Pare-feu applicatif (WAF), Défense côté client Faible : <script> basique, Élevé : contournement encodé XSS (Stocké) Pare-feu applicatif (WAF), Défense côté client Faible : script persistant dans le livre d’or Téléversement de fichiers Pare-feu applicatif (WAF) Faible : téléversement de shell PHP, Élevé : filtrage d’extension Force brute Défense Bot standard Tentatives de connexion automatisées
Définissez le niveau de sécurité sur /dvwa/security.php après la connexion :
Faible — Aucune validation des entrées. Chaque attaque fonctionne. Idéal pour les démonstrations de signatures WAF.
Moyen — Filtrage basique. Certaines attaques nécessitent un encodage ou des techniques de contournement.
Élevé — Filtrage renforcé. Seules les techniques avancées réussissent. Utile pour montrer les limites du WAF.
Impossible — Implémentation entièrement sécurisée. Démontre un code défensif approprié.
DVWA nécessite une configuration unique de la base de données après le premier déploiement :
Accédez à http://<PUBLIC_IP>/dvwa/setup.php
Cliquez sur Create / Reset Database
Connectez-vous avec admin / password
Chemin /vampi/Image erev0s/vampi:latest avec point d’entrée gunicorn (4 workers)Instances 4 (ports 5101-5104), persistance via ip_hash (SQLite par instance) Ressources 0,5 CPU / 512 Mio de RAM par instance Framework Python / Flask / gunicorn Projet github.com/erev0s/VAmPI
VAmPI est conçu spécifiquement pour tester l’OWASP API Security Top 10. Il fournit une API REST réaliste avec des vulnérabilités délibérées. Chaque instance exécute gunicorn avec 4 workers et sa propre base de données SQLite. La session persistante ip_hash garantit que l’inscription et la connexion depuis la même IP client atteignent toujours la même instance.
Scénario OWASP API Top 10 Méthode Autorisation au niveau des objets compromise (BOLA) API1 Accès aux données d’autres utilisateurs en manipulant les ID Authentification compromise API2 Gestion faible des jetons, absence de limitation de débit Exposition excessive des données API3 L’API retourne plus de données que nécessaire au client Affectation de masse API6 Modification des champs admin via des paramètres inattendus Injection SQL API8 Injection via les paramètres de l’API Gestion incorrecte des ressources API9 Points de terminaison d’API non documentés
# Enregistrer un nouvel utilisateur
curl -X POST " http://<PUBLIC_IP>/vampi/users/v1/register " \
-H " Content-Type: application/json " \
-d ' {"username":"test","password":"test123","email":"test@test.com"} '
curl -X POST " http://<PUBLIC_IP>/vampi/users/v1/login " \
-H " Content-Type: application/json " \
-d ' {"username":"test","password":"test123"} '
# Lister les utilisateurs (exposition excessive des données)
curl " http://<PUBLIC_IP>/vampi/users/v1 "
Chemin /httpbin/Image kennethreitz/httpbin:latest avec remplacement de la commande gunicorn (-w 4 -k gevent --timeout 30)Instances 4 (ports 8201-8204), round-robin (sans état) Ressources 0,5 CPU / 256 Mio de RAM par instance Framework Python / Flask / gunicorn + gevent Projet httpbin.org
httpbin est un service simple de requête/réponse HTTP utile pour les démonstrations d’API de base, les tests des en-têtes de requête et la vérification du comportement du proxy.
Point de terminaison Objectif /httpbin/getRetourne les données de la requête GET (en-têtes, arguments, origine) /httpbin/postRetourne les données de la requête POST (corps, formulaire, JSON) /httpbin/headersRetourne les en-têtes de la requête /httpbin/ipRetourne l’IP d’origine /httpbin/user-agentRetourne l’en-tête User-Agent /httpbin/status/:codeRetourne le code de statut HTTP spécifié /httpbin/delay/:secondsRetarde la réponse de N secondes /httpbin/anythingRetourne tout ce qui est transmis dans la requête
# Vérifier les en-têtes que voit le serveur d'origine (utile pour vérifier l'injection d'en-têtes F5 XC)
curl -s " http://<PUBLIC_IP>/httpbin/headers " | jq .
# Tester un code de statut HTTP spécifique
curl -s -o /dev/null -w " %{http_code} " " http://<PUBLIC_IP>/httpbin/status/403 "
Chemin /whoami/Image traefik/whoami:latestInstances 4 (ports 8082-8085), round-robin (sans état) Ressources 0,25 CPU / 64 Mio de RAM par instance Framework Go Projet github.com/traefik/whoami
whoami est le serveur d’écho de requêtes léger de Traefik. Il affiche chaque détail de la requête HTTP entrante telle que la voit le serveur d’origine — nom d’hôte, adresses IP, tous les en-têtes, méthode et URL. Il s’agit de l’outil de diagnostic le plus important pour vérifier que F5 XC injecte les bons en-têtes.
Cas d’utilisation Ce qu’il faut rechercher Vérifier l’injection d’en-têtes F5 XC En-têtes X-Forwarded-For, True-Client-IP, X-Volterra-* Confirmer la visibilité de l’IP client X-Real-IP vs RemoteAddrDéboguer les faux positifs du WAF Comparer les en-têtes de requête avant/après F5 XC Valider le marquage de la défense bot En-têtes X-Volterra-Bot-Type, X-Volterra-Bot-Verified Vérifier la terminaison TLS X-Forwarded-Proto affiche https lorsque TLS se termine au niveau de F5 XC
# Requête de base -- voir ce que reçoit le serveur d'origine
curl " http://<PUBLIC_IP>/whoami/ "
# Simuler une requête via F5 XC (avec en-têtes injectés)
curl " http://<PUBLIC_IP>/whoami/ " \
-H " X-Forwarded-For: 203.0.113.50 " \
-H " True-Client-IP: 203.0.113.50 " \
-H " X-Forwarded-Proto: https "
Exemple de sortie :
RemoteAddr: 172.17.0.1:55118
True-Client-Ip: 203.0.113.50
X-Forwarded-For: 203.0.113.50, 10.0.0.1
X-Real-Ip: 104.219.105.84
DVGA est conçu spécifiquement pour tester les vulnérabilités propres à GraphQL. Il fournit un IDE GraphiQL sur /dvga/ pour l’exploration interactive des requêtes et un point de terminaison d’API GraphQL sur /dvga/graphql. Chaque instance utilise sa propre base de données SQLite, de sorte que les sessions persistantes ip_hash garantissent un état cohérent.
Scénario Catégorie Vecteur d’attaque Injection GraphQL Sécurité des API Requêtes malveillantes via interpolation de chaînes Déni de service Sécurité des API Requêtes profondément imbriquées, requêtes par lot, épuisement des ressources Contournement d’autorisation Sécurité des API Accès à des données non autorisées via GraphQL Divulgation d’informations Sécurité des API Requêtes d’introspection révélant les détails du schéma Attaque par lot Sécurité des API Plusieurs opérations dans une seule requête
# Interface GraphiQL (IDE interactif)
curl -sf " http://<PUBLIC_IP>/dvga/ " -o /dev/null -w " %{http_code} "
# Requête d'introspection -- énumérer le schéma complet
curl -s " http://<PUBLIC_IP>/dvga/graphql " \
-H " Content-Type: application/json " \
-d ' {"query":"{ __schema { types { name fields { name } } } }"} '
# Lister les publications (exemple de requête)
curl -s " http://<PUBLIC_IP>/dvga/graphql " \
-H " Content-Type: application/json " \
-d ' {"query":"{ pastes { title content } }"} '
# Créer une publication (mutation)
curl -s " http://<PUBLIC_IP>/dvga/graphql " \
-H " Content-Type: application/json " \
-d ' {"query":"mutation { createPaste(title:\"test\", content:\"hello\", public:true) { paste { title } } }"} '
Chemin /restaurant/Image Construction personnalisée à partir de theowni/Damn-Vulnerable-RESTaurant-API-Game Instances 4 (ports 8301-8304), round-robin (PostgreSQL partagé) Ressources 0,5 CPU / 256 Mio de RAM par instance Base de données PostgreSQL 15.4 partagé (conteneur restaurant-db, 0,5 CPU / 512 Mio) Framework Python / FastAPI / PostgreSQL Identifiants admin / password (PostgreSQL)Projet github.com/theowni/Damn-Vulnerable-RESTaurant-API-Game
RESTaurant est une API REST vulnérable et ludique couvrant l’OWASP API Security Top 10 2023. Elle utilise FastAPI avec une documentation Swagger UI automatique sur /restaurant/docs. Les 4 instances partagent une seule base de données PostgreSQL, de sorte que la répartition de charge round-robin fonctionne sans sessions persistantes.
Scénario OWASP API Top 10 2023 Méthode Autorisation au niveau des objets compromise (BOLA) API1 Accès aux commandes d’autres utilisateurs en manipulant les ID Authentification compromise API2 Gestion faible des jetons, bourrage de credentials Autorisation au niveau des propriétés d’objet compromise API3 Affectation de masse sur les champs du profil utilisateur Consommation de ressources non restreinte API4 Absence de limitation de débit sur les points de terminaison Autorisation au niveau des fonctions compromise (BFLA) API5 Accès aux points de terminaison admin en tant qu’utilisateur ordinaire Falsification de requête côté serveur (SSRF) API7 Manipulation des requêtes d’URL côté serveur Mauvaise configuration de la sécurité API8 Messages d’erreur verbeux, identifiants par défaut
curl -sf " http://<PUBLIC_IP>/restaurant/docs " -o /dev/null -w " %{http_code} "
curl -s " http://<PUBLIC_IP>/restaurant/openapi.json " | jq .info
# BOLA -- accéder à la commande d'un autre utilisateur (après authentification)
curl -s " http://<PUBLIC_IP>/restaurant/orders/1 " \
-H " Authorization: Bearer <token> "
# BFLA -- tenter une action admin en tant qu'utilisateur ordinaire
curl -s -X POST " http://<PUBLIC_IP>/restaurant/admin/users " \
-H " Authorization: Bearer <user_token> " \
-H " Content-Type: application/json "
Port 8888 (dédié — sans préfixe de chemin)Images crapi/crapi-web, crapi/crapi-identity, crapi/crapi-community, crapi/crapi-workshop, PostgreSQL, MongoDB, MailHogInstances 7 microservices (instance unique chacun) Ressources ~3,0 CPU / ~2,0 Gio de RAM au total Framework React SPA + microservices Java/Go/Python Projet github.com/OWASP/crAPI
crAPI est le projet phare de l’OWASP pour les tests de sécurité des API. Il s’exécute en tant que 7 microservices sur un port dédié (8888) car le React SPA encode en dur ses chemins d’API et ne peut pas être servi derrière un préfixe de chemin. Le NSG autorise le trafic entrant sur le port 8888.
MailHog capture tous les e-mails envoyés par crAPI (vérification de compte, réinitialisation du mot de passe). Accédez à MailHog via un tunnel SSH sur le port 18025.
Catégorie Vulnérabilités BOLA (Autorisation au niveau des objets compromise) Accès aux véhicules, commandes et rapports d’autres utilisateurs BFLA (Autorisation au niveau des fonctions compromise) Escalade vers admin, accès aux points de terminaison restreints Affectation de masse Modification de champs protégés (rôle, solde) via l’API SSRF (Falsification de requête côté serveur) Manipulation des récupérations d’URL côté serveur Manipulation JWT Falsification ou modification de jetons JWT pour l’élévation de privilèges Injection NoSQL Injection de requêtes dans les points de terminaison soutenus par MongoDB Exposition excessive des données L’API retourne des données utilisateur sensibles
# Vérifier que crAPI est en cours d'exécution
curl -sf " http://<PUBLIC_IP>:8888 " -o /dev/null -w " %{http_code} "
# Inscrire un nouvel utilisateur
curl -s -X POST " http://<PUBLIC_IP>:8888/identity/api/auth/signup " \
-H " Content-Type: application/json " \
-d ' {"name":"Test User","email":"test@example.com","number":"1234567890","password":"Test1234!"} '
curl -s -X POST " http://<PUBLIC_IP>:8888/identity/api/auth/login " \
-H " Content-Type: application/json " \
-d ' {"email":"test@example.com","password":"Test1234!"} '
# Accéder à MailHog (via tunnel SSH pour la vérification par e-mail)
# ssh -L 18025:localhost:18025 azureuser@<PUBLIC_IP>
# Puis ouvrir http://localhost:18025 dans votre navigateur
Port 8888 -> crapi-web (React SPA + nginx)
-> crapi-identity (Java, authentification utilisateur, JWT)
-> crapi-community (Go, forums, publications)
-> crapi-workshop (Python, service véhicule)
-> crapi-postgres (PostgreSQL)
-> crapi-mailhog (capture d'e-mails, port 18025)
Cas d’utilisation de démonstration Application principale Application secondaire WAF — Injection SQL DVWA Juice Shop WAF — XSS DVWA Juice Shop WAF — Injection de commandes DVWA — Sécurité des API — BOLA VAmPI — Sécurité des API — Contournement d’authentification VAmPI Juice Shop Sécurité des API — Exposition de données VAmPI httpbin Défense Bot — Force brute DVWA Juice Shop Défense Bot — Scraping Juice Shop — Défense côté client — XSS basé sur le DOM Juice Shop — Défense côté client — XSS stocké DVWA Juice Shop Défense côté client — Skimmer de carte CSD Demo — Défense côté client — Formjacker CSD Demo — Défense côté client — Enregistreur de frappe CSD Demo — Défense côté client — Cryptomineur CSD Demo — Défense côté client — Détournement DOM CSD Demo — Sécurité des API — Injection GraphQL DVGA — Sécurité des API — DoS GraphQL DVGA — Sécurité des API — OWASP API Top 10 2023 RESTaurant crAPI Sécurité des API — BFLA RESTaurant crAPI Sécurité des API — Affectation de masse crAPI RESTaurant Sécurité des API — SSRF crAPI RESTaurant Sécurité des API — Manipulation JWT crAPI — Sécurité des API — Injection NoSQL crAPI — Tests de connectivité de base httpbin — Diagnostics des requêtes whoami httpbin Vérification de l’injection d’en-têtes whoami —