Introduction au Chaos Engineering¶
Principe¶
Le chaos engineering consiste à injecter délibérément des anomalies dans un système pour observer son comportement sous stress et former les équipes à diagnostiquer des incidents.
PerfShop implémente cinq familles de chaos :
🔧 Chaos Backend → dégrade le serveur Spring Boot (sliders 0–100%)
🖥️ Chaos Frontend → dégrade le navigateur de l'utilisateur (sliders 0–100%)
⚡ Chaos Fonctionnel → injecte des exceptions JVM dans le parcours applicatif (niveaux 0–3)
💼 Chaos Métier → injecte des anomalies dans la logique e-commerce (niveaux 0–3)
🔒 Chaos Sécurité → injecte des failles web OWASP Top 10 (niveaux 0–4)
Panneau de contrôle¶
Accessible via https://perfshop-chaos.perfshop.io.
- Onglet Backend : 7 sliders 0–100% agissant sur le container
perfshop-app - Onglet Frontend : 4 sliders 0–100% agissant sur le navigateur des visiteurs
- Onglet Scripting : 4 cartes cliquables (niveaux 0 à 3) pour la complexité des tokens
- Onglet Chaos Fonctionnel : 4 cartes cliquables (niveaux 0 à 3) pour les exceptions JVM
- Onglet Chaos Métier : 4 cartes cliquables (niveaux 0 à 3) pour les anomalies fonctionnelles
- Onglet Chaos Sécurité : 5 cartes cliquables (niveaux 0 à 4) pour les failles OWASP
Principe des sliders¶
Les sliders ne sont pas des pourcentages arbitraires — ils sont calibrés pour que la valeur corresponde à l'impact réel :
| Valeur slider | Délai Thread Pool | Délai Slow Query | FPS Navigateur |
|---|---|---|---|
| 0% | 0ms | 0ms | ~144 |
| 25% | 750ms | 375ms | ~100 |
| 50% | 1500ms | 2000ms | ~40 |
| 75% | 3000ms | 4000ms | ~20 |
| 100% | 5000ms | 6000ms | ~10 |
Cohérence des formules¶
Toutes les anomalies à base de délai suivent la même philosophie progressive : pas de saut brutal entre paliers. Exemple pour Thread Pool :
1–24% → intensity × 20ms (dégradation légère, perceptible)
25–49% → intensity × 30ms (dégradation modérée)
50–74% → 1500ms fixe (dégradation forte)
75–99% → 3000ms fixe (dégradation sévère)
100% → 5000ms fixe (saturation)
Cette progressivité permet d'observer une dégradation graduelle dans Grafana plutôt qu'un saut de 0 à 500ms difficile à analyser.
Corrélation anomalie → métriques¶
C'est le cœur de l'exercice pédagogique. Chaque anomalie a une signature reconnaissable dans les dashboards :
| Anomalie | Métrique principale | Métriques secondaires |
|---|---|---|
| CPU Backend | cpu_percent ↑ |
http_latency_p99 ↑ |
| Memory Leak Backend | jvm_heap_used ↑ |
gc_pause_time ↑ |
| Thread Pool | tomcat_busy_threads ↑ |
http_latency ↑ |
| DB Pool | hikaricp_active ↑ |
connection_pending ↑ |
| Slow Query | http_latency_p99 ↑ |
hikaricp_acquire_ms ↑ |
| Deadlock | 5xx_rate ↑ |
threads_blocked ↑ |
| Network Timeout | http_latency ↑ |
503_rate ↑ (à 75%+) |
| CPU Frontend | fps ↓ |
long_tasks_per_sec ↑ |
| Memory Leak Frontend | heap_js_mb ↑ continu |
plafonne à 1.2 Go |
| DOM Flood | long_tasks_per_sec ↑ |
dom_node_count oscille |
| Fetch Flood | fetch_req_per_sec ↑ |
débit HTTP backend ↑ |
| F1 NPE paiement | span Tempo ERROR NullPointerException |
5xx_rate ↑ sur /api/orders |
| F2 SOE calcul | span Tempo ERROR StackOverflowError |
5xx_rate ↑ sur /api/orders |
| F3 OOM catalogue | span Tempo ERROR OutOfMemoryError |
jvm_heap_used ↑ non récupéré |
| A1 TVA incorrecte | logs [BusinessChaos][A1] |
montant TTC sous-calculé |
| A2 Arrondi prix | logs [BusinessChaos][A2] |
écart prix panier vs catalogue |
| A3 Stock non décrémenté | logs [BusinessChaos][A3] |
stock inchangé post-commande |
| A5 Double commande | 5xx_rate ↑ possible |
deux commandes identiques en liste |
| A8 Race condition | logs [BusinessChaos][A8] |
survente détectable sous charge |
| A11 Token logout | logs [BusinessChaos][A11] |
API accessible 30s post-logout |
| S1 Injection SQL | logs [SecurityChaos][S1] |
comportement anormal sur /api/products/search |
| S2 IDOR | logs [SecurityChaos][S2] |
accès à des commandes d'autres utilisateurs |
| S3 Hash exposé | logs [SecurityChaos][S3] |
champ password dans /api/auth/me |
| S4 XSS stocké | logs [SecurityChaos][S4] |
payload HTML non échappée en base |
| S5 Prix falsifié | logs [SecurityChaos][S5] |
montant commande ≠ prix catalogue |
| S6 Timing attack | logs [SecurityChaos][S6] |
δt login ~300ms vs <5ms |
| S7 Token faible | logs [SecurityChaos][S7] |
header X-Debug-Token décodable |
| S8 Path Traversal | logs [SecurityChaos][S8] |
contenu fichier dans réponse /invoice |
| S9 Mass Assignment | logs [SecurityChaos][S9] |
email/password modifiés via PUT profil |
| S10 Stats portail | logs [SecurityChaos][S10] |
email superadmin exposé sans auth |
| S11 SQLi portail | logs [SecurityChaos][S11] |
bypass login portail → adminToken |
| S12 Privesc | logs [SecurityChaos][S12] |
compte promu superAdmin via IDOR |
Pertinence pédagogique¶
Chaque anomalie est calquée sur un problème réel rencontré en production :
| Anomalie | Cause réelle en production |
|---|---|
| Thread Pool | Appels synchrones vers un service externe lent sans timeout |
| Slow Query | Index manquants découverts sous charge, FetchType.EAGER sur grandes collections |
| Deadlock | Deux transactions acquièrent des verrous dans l'ordre inverse |
| Network Timeout | Service de paiement externe dégradé, absence de circuit breaker |
| Memory Leak JS | Event listeners non supprimés dans useEffect, stores Redux sans purge |
| DOM Flood | Re-render complet d'une liste à chaque keystroke sans useMemo |
| Fetch Flood | Appels API dans un useEffect sans debounce |
| A1 TVA incorrecte | Taux fiscal obsolète hard-codé, non mis à jour lors d'un changement légal |
| A2 Arrondi prix | Conversion float → integer sans BigDecimal, perte de centimes en volume |
| A3 Stock non décrémenté | Mise à jour de stock oubliée dans un cas de test d'intégration absent |
| A5 Double commande | Absence d'idempotence sur un endpoint critique (bouton "Commander") |
| A8 Race condition | SELECT puis UPDATE non atomiques sans verrou → survente en production |
| A11 Token logout | Session invalidée côté serveur mais cached côté load balancer (TTL résiduel) |
| S1 Injection SQL | Requêtes non paramétrées — OWASP A03 endémique dans les vieilles codebases |
| S2 IDOR | Absence de vérification d'appartenance — erreur classique sur les APIs REST |
| S3 Hash exposé | DTO généré automatiquement (JPA/Lombok) incluant des champs sensibles |
| S4 XSS stocké | Données utilisateur stockées et restituées sans échappement HTML |
| S5 Prix falsifié | Confiance aveugle au body client sans revalidation côté serveur |
| S6 Timing attack | BCrypt intentionnellement lent — différence de timing détectable par script |
| S7 Token HMAC faible | Clé secrète hardcodée ou triviale, découvrable dans les sources |
| S8 Path Traversal | Paramètre utilisé dans un chemin sans validation ni canonicalisation |
| S9 Mass Assignment | Mapping automatique entité ↔ DTO sans whitelist de champs autorisés |
| S10 Stats sans auth | Endpoint interne exposé sans authentification — information disclosure |
| S11 SQLi portail | Formulaire interne non paramétré — même cause que S1 mais sur surface admin |
| S12 Privesc IDOR | Absence de vérification de rôle avant action privilégiée |
Utilisation pédagogique¶
Mode démo¶
Le formateur active les anomalies une par une et montre la corrélation en direct dans Grafana ou le dashboard HTML.
Mode hackathon¶
Les apprenants ont accès au dashboard de monitoring mais pas au panneau de contrôle. Le formateur active des anomalies à la volée. Les apprenants doivent :
- Identifier quelle(s) anomalie(s) est active
- Expliquer la chaîne de causalité
- Proposer une action corrective
Pour le Chaos Sécurité, les apprenants disposent d'un accès API et doivent :
- Identifier les failles actives (réponses inattendues, champs supplémentaires, timing, etc.)
- Les exploiter pour démontrer leur impact
- Documenter la faille au format OWASP (titre, vecteur, impact, remédiation)
Mode formation¶
Les apprenants ont accès à tout. Ils explorent les anomalies en autonomie et documentent leurs observations.
Combinaisons intéressantes¶
Les anomalies sont combinables — c'est ce qui rend la plateforme réaliste. En production les problèmes arrivent rarement seuls :
| Combinaison | Effet observé |
|---|---|
| Slow Query + DB Pool | Connexions tenues longtemps → pool épuisé → toutes les requêtes timeout |
| Thread Pool + Network | Threads bloqués + délais réseau → cascade vers saturation Tomcat |
| CPU Burn + Fetch Flood | CPU saturé + flood réseau → dégradation complète de l'expérience utilisateur |
| Memory Leak + CPU | GC fréquent → pics CPU parasites → métriques CPU instables |