Aller au contenu

Applications

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.

CheminApplicationMéthode HTTPRéponse attendue
/Page d’accueilGET200 HTML avec liens vers toutes les applications
/healthVérification d’étatGET200 JSON {"status":"healthy","component":"origin-server",...}
/juice-shop/Juice ShopGET200 HTML (Angular SPA, ~75 Ko)
/juice-shop/rest/products/search?q=API Juice ShopGET200 JSON {"status":"success","data":[...]} (36 produits)
/dvwa/DVWAGET302 redirection vers /dvwa/login.php
/dvwa/login.phpConnexion DVWAGET200 HTML formulaire de connexion
/dvwa/setup.phpConfiguration DVWAGET200 HTML (initialisation de la base de données au premier démarrage)
/vampi/VAmPIGET200 HTML (documentation API)
/vampi/users/v1API VAmPIGET200 JSON {"users":[...]}
/vampi/users/v1/registerAPI VAmPIPOST200 JSON {"status":"success",...}
/vampi/users/v1/loginAPI VAmPIPOST200 JSON {"auth_token":"...","status":"success"}
/httpbin/gethttpbinGET200 JSON avec les détails de la requête
/httpbin/posthttpbinPOST200 JSON avec les données publiées
/httpbin/headershttpbinGET200 JSON {"headers":{...}}
/httpbin/status/:codehttpbinGETRetourne le code de statut HTTP spécifié
/whoami/whoamiGET200 texte brut avec le nom d’hôte, l’IP et tous les en-têtes
/csd-demo/CSD DemoGET200 HTML formulaire de paiement avec panneau d’attaque
/csd-demo/dashboardVue attaquant CSDGET200 HTML affichant les données exfiltrées
/csd-demo/healthÉtat CSDGET200 JSON {"status":"healthy","component":"csd-demo",...}
/csd-demo/exfil/logJournal d’exfiltration CSDGET200 tableau JSON des données capturées
/dvga/DVGA GraphiQLGET200 HTML (IDE GraphiQL)
/dvga/graphqlAPI GraphQL DVGAPOST200 JSON réponse GraphQL
/restaurant/RESTaurantGET200 (redirige vers la documentation)
/restaurant/docsSwagger RESTaurantGET200 HTML (interface Swagger FastAPI)
/restaurant/openapi.jsonOpenAPI RESTaurantGET200 JSON spécification OpenAPI
http://<PUBLIC_IP>:8888crAPIGET200 HTML (SPA)
http://<PUBLIC_IP>:8888/identity/api/auth/signupInscription crAPIPOST200 JSON
http://<PUBLIC_IP>:8888/identity/api/auth/loginConnexion crAPIPOST200 JSON {"token":"..."}
Chemin/juice-shop/
Imagebkimminich/juice-shop:latest
Instances4 (ports 3001-3004), persistance via hash $cookie_token, cache proxy (TTL 60 s)
Ressources2 CPU / 1 Gio de RAM par instance
FrameworkNode.js / Angular
Projetowasp.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énarioCatégorieVecteur d’attaque
Contournement de connexion par injection SQLPare-feu applicatif (WAF)' OR 1=1-- dans le champ email de connexion
XSS réfléchiPare-feu applicatif (WAF), Défense côté clientInjection de script via le paramètre de recherche
XSS basé sur le DOMDéfense côté clientCharge utile dans le fragment d’URL
Authentification compromisePare-feu applicatif (WAF)Attaque par force brute, manipulation JWT
Abus d’APISécurité des APIAccès non autorisé aux points de terminaison /api/
Exposition de données sensiblesSécurité des APIAccès aux données utilisateur sans autorisation
CSRFPare-feu applicatif (WAF)Falsification de requête inter-sites sur les modifications de profil
Fenêtre de terminal
curl -s "http://<PUBLIC_IP>/juice-shop/" -o /dev/null -w "%{http_code}"
Chemin/dvwa/
Imagedvwa-fpm:latest personnalisée (php-fpm + nginx, construite à partir de ghcr.io/digininja/dvwa:latest)
Instances4 (ports 8101-8104), persistance via hash $cookie_PHPSESSID
Ressources0,5 CPU / 256 Mio de RAM par instance
Base de donnéesMariaDB 10.11 partagée (conteneur dvwa-db, 1 CPU / 768 Mio)
FrameworkPHP 8 / php-fpm / MariaDB
Identifiantsadmin / 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énarioCatégorieNiveau de sécurité
Injection SQLPare-feu applicatif (WAF)Faible : ' OR 1=1# trivial, Élevé : SQLi aveugle
Injection de commandesPare-feu applicatif (WAF)Faible : ; ls, Élevé : caractères filtrés
Inclusion de fichiersPare-feu applicatif (WAF)Faible : traversée de chemin directe, Élevé : assaini
XSS (Réfléchi)Pare-feu applicatif (WAF), Défense côté clientFaible : <script> basique, Élevé : contournement encodé
XSS (Stocké)Pare-feu applicatif (WAF), Défense côté clientFaible : script persistant dans le livre d’or
Téléversement de fichiersPare-feu applicatif (WAF)Faible : téléversement de shell PHP, Élevé : filtrage d’extension
Force bruteDéfense Bot standardTentatives 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 :

  1. Accédez à http://<PUBLIC_IP>/dvwa/setup.php
  2. Cliquez sur Create / Reset Database
  3. Connectez-vous avec admin / password
Chemin/vampi/
Imageerev0s/vampi:latest avec point d’entrée gunicorn (4 workers)
Instances4 (ports 5101-5104), persistance via ip_hash (SQLite par instance)
Ressources0,5 CPU / 512 Mio de RAM par instance
FrameworkPython / Flask / gunicorn
Projetgithub.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énarioOWASP API Top 10Méthode
Autorisation au niveau des objets compromise (BOLA)API1Accès aux données d’autres utilisateurs en manipulant les ID
Authentification compromiseAPI2Gestion faible des jetons, absence de limitation de débit
Exposition excessive des donnéesAPI3L’API retourne plus de données que nécessaire au client
Affectation de masseAPI6Modification des champs admin via des paramètres inattendus
Injection SQLAPI8Injection via les paramètres de l’API
Gestion incorrecte des ressourcesAPI9Points de terminaison d’API non documentés
Fenêtre de terminal
# 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"}'
# Connexion
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/
Imagekennethreitz/httpbin:latest avec remplacement de la commande gunicorn (-w 4 -k gevent --timeout 30)
Instances4 (ports 8201-8204), round-robin (sans état)
Ressources0,5 CPU / 256 Mio de RAM par instance
FrameworkPython / Flask / gunicorn + gevent
Projethttpbin.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 terminaisonObjectif
/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
Fenêtre de terminal
# 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/
Imagetraefik/whoami:latest
Instances4 (ports 8082-8085), round-robin (sans état)
Ressources0,25 CPU / 64 Mio de RAM par instance
FrameworkGo
Projetgithub.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’utilisationCe qu’il faut rechercher
Vérifier l’injection d’en-têtes F5 XCEn-têtes X-Forwarded-For, True-Client-IP, X-Volterra-*
Confirmer la visibilité de l’IP clientX-Real-IP vs RemoteAddr
Déboguer les faux positifs du WAFComparer les en-têtes de requête avant/après F5 XC
Valider le marquage de la défense botEn-têtes X-Volterra-Bot-Type, X-Volterra-Bot-Verified
Vérifier la terminaison TLSX-Forwarded-Proto affiche https lorsque TLS se termine au niveau de F5 XC
Fenêtre de terminal
# 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 :

Hostname: 534c5084e169
IP: 127.0.0.1
RemoteAddr: 172.17.0.1:55118
GET / HTTP/1.1
Host: 20.12.78.159
User-Agent: curl/8.5.0
Accept: */*
True-Client-Ip: 203.0.113.50
X-Forwarded-For: 203.0.113.50, 10.0.0.1
X-Forwarded-Proto: https
X-Real-Ip: 104.219.105.84
Chemin/dvga/
Imagedolevf/dvga:latest
Instances4 (ports 5201-5204), persistance via ip_hash (SQLite par instance)
Ressources0,5 CPU / 256 Mio de RAM par instance
FrameworkPython / Flask / GraphQL
Projetgithub.com/dolevf/Damn-Vulnerable-GraphQL-Application

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énarioCatégorieVecteur d’attaque
Injection GraphQLSécurité des APIRequêtes malveillantes via interpolation de chaînes
Déni de serviceSécurité des APIRequêtes profondément imbriquées, requêtes par lot, épuisement des ressources
Contournement d’autorisationSécurité des APIAccès à des données non autorisées via GraphQL
Divulgation d’informationsSécurité des APIRequêtes d’introspection révélant les détails du schéma
Attaque par lotSécurité des APIPlusieurs opérations dans une seule requête
Fenêtre de terminal
# 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/
ImageConstruction personnalisée à partir de theowni/Damn-Vulnerable-RESTaurant-API-Game
Instances4 (ports 8301-8304), round-robin (PostgreSQL partagé)
Ressources0,5 CPU / 256 Mio de RAM par instance
Base de donnéesPostgreSQL 15.4 partagé (conteneur restaurant-db, 0,5 CPU / 512 Mio)
FrameworkPython / FastAPI / PostgreSQL
Identifiantsadmin / password (PostgreSQL)
Projetgithub.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énarioOWASP API Top 10 2023Méthode
Autorisation au niveau des objets compromise (BOLA)API1Accès aux commandes d’autres utilisateurs en manipulant les ID
Authentification compromiseAPI2Gestion faible des jetons, bourrage de credentials
Autorisation au niveau des propriétés d’objet compromiseAPI3Affectation de masse sur les champs du profil utilisateur
Consommation de ressources non restreinteAPI4Absence de limitation de débit sur les points de terminaison
Autorisation au niveau des fonctions compromise (BFLA)API5Accès aux points de terminaison admin en tant qu’utilisateur ordinaire
Falsification de requête côté serveur (SSRF)API7Manipulation des requêtes d’URL côté serveur
Mauvaise configuration de la sécuritéAPI8Messages d’erreur verbeux, identifiants par défaut
Fenêtre de terminal
# Interface Swagger
curl -sf "http://<PUBLIC_IP>/restaurant/docs" -o /dev/null -w "%{http_code}"
# Spécification OpenAPI
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"
Port8888 (dédié — sans préfixe de chemin)
Imagescrapi/crapi-web, crapi/crapi-identity, crapi/crapi-community, crapi/crapi-workshop, PostgreSQL, MongoDB, MailHog
Instances7 microservices (instance unique chacun)
Ressources~3,0 CPU / ~2,0 Gio de RAM au total
FrameworkReact SPA + microservices Java/Go/Python
Projetgithub.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égorieVulné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 masseModification 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 JWTFalsification ou modification de jetons JWT pour l’élévation de privilèges
Injection NoSQLInjection de requêtes dans les points de terminaison soutenus par MongoDB
Exposition excessive des donnéesL’API retourne des données utilisateur sensibles
Fenêtre de terminal
# 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!"}'
# Se connecter
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-mongo (MongoDB)
-> crapi-mailhog (capture d'e-mails, port 18025)
Cas d’utilisation de démonstrationApplication principaleApplication secondaire
WAF — Injection SQLDVWAJuice Shop
WAF — XSSDVWAJuice Shop
WAF — Injection de commandesDVWA
Sécurité des API — BOLAVAmPI
Sécurité des API — Contournement d’authentificationVAmPIJuice Shop
Sécurité des API — Exposition de donnéesVAmPIhttpbin
Défense Bot — Force bruteDVWAJuice Shop
Défense Bot — ScrapingJuice Shop
Défense côté client — XSS basé sur le DOMJuice Shop
Défense côté client — XSS stockéDVWAJuice Shop
Défense côté client — Skimmer de carteCSD Demo
Défense côté client — FormjackerCSD Demo
Défense côté client — Enregistreur de frappeCSD Demo
Défense côté client — CryptomineurCSD Demo
Défense côté client — Détournement DOMCSD Demo
Sécurité des API — Injection GraphQLDVGA
Sécurité des API — DoS GraphQLDVGA
Sécurité des API — OWASP API Top 10 2023RESTaurantcrAPI
Sécurité des API — BFLARESTaurantcrAPI
Sécurité des API — Affectation de massecrAPIRESTaurant
Sécurité des API — SSRFcrAPIRESTaurant
Sécurité des API — Manipulation JWTcrAPI
Sécurité des API — Injection NoSQLcrAPI
Tests de connectivité de basehttpbin
Diagnostics des requêteswhoamihttpbin
Vérification de l’injection d’en-têteswhoami