Session 8 — Chaos Sécurité — 9 failles OWASP implémentées¶
Durée : ~8 heures (3 conversations Claude) Objectif initial : Implémenter le Chaos Sécurité selon le prompt de conception livré en Session 7 Objectif final : 9 failles OWASP opérationnelles + UI chaos-admin + onglet monitoring + 5 passes de revue de code
🎯 Réalisations¶
1. SecurityChaosService.java — service central¶
Temps : ~1h30 Difficulté : ⭐⭐⭐⭐
Service Java construit sur le même pattern que BusinessChaosService :
AtomicInteger level(0–3) + 9AtomicLongcompteurs par failleConcurrentLinkedDequeactivity log ring buffer 200 entrées max- 9 flags booléens :
isInjectionActive(),isIdorActive(),isPasswordExposed(),isXssActive(),isPriceTamperingActive(),isTimingAttackActive(),isWeakTokenActive(),isPathTraversalActive(),isMassAssignmentActive()
Méthodes utilitaires exposées aux controllers¶
| Méthode | Faille | Comportement |
|---|---|---|
recordSqlInjection(q, email) |
S1 | Détecte les patterns SQLi dans le paramètre q |
recordIdorAccess(requesterId, ownerId, orderId) |
S2 | Logue l'accès cross-user |
recordPasswordHashExposed(email) |
S3 | Incrémente compteur S3 |
processShippingAddress(addr) |
S4 | Retourne l'adresse non sanitisée en N2+ |
recordPriceTampering(email, orig, received) |
S5 | Logue l'écart prix |
recordTimingAttack(email, exists, ms) |
S6 | Logue le timing et le δt |
generateWeakToken(userId) |
S7 | HMAC-SHA256 clé "secret123" |
validateWeakToken(token) |
S7 | Vérifie la signature |
processInvoiceFormat(format, id, email) |
S8 | Simule le path traversal |
detectAndRecordMassAssignment(body, user) |
S9 | Détecte champs sensibles dans le body |
Token S7 — format détaillé¶
HMAC calculé via javax.crypto.Mac JDK natif — zéro dépendance Maven externe.
Records Java 17 :
record WeakTokenValidation(boolean valid, Long userId, Long timestamp, String error) {}
record PathTraversalResult(boolean traversalAttempted, String filename, String content, String detectedPath) {}
S8 — simulation pédagogique¶
simulateFileContent() retourne du contenu fictif pour les chemins reconnus
(passwd, application.yml, .env, shadow) afin de montrer l'impact d'un
vrai path traversal sans accéder au filesystem réel.
Champs sensibles S9¶
role n'existe pas dans l'entité User — décision architecturale prise lors de
la conception pour rester fidèle au modèle de données réel.
2. SecurityChaosController.java — endpoints admin + publics¶
Temps : ~30 min Difficulté : ⭐⭐
Pattern identique à BusinessChaosController, sous @RequestMapping("/api") :
Endpoints admin (auth AdminAuth requise) :
POST /api/admin/chaos/security → setLevel(level)
GET /api/admin/chaos/security/status → statut complet + compteurs
POST /api/admin/chaos/security/reset → reset niveau + compteurs
POST /api/admin/chaos/security/logs/clear
Endpoints publics (sans auth, pour le monitoring) :
GET /api/chaos/public/security/status
GET /api/chaos/public/security/logs
GET /api/chaos/public/security/faults?level=N
3. Modifications des controllers existants — 7 fichiers¶
Temps : ~2h Difficulté : ⭐⭐⭐⭐
Chaque faille est un hook conditionnel dans le controller cible. Niveau 0 = comportement 100% nominal, aucun impact.
ProductController — S1¶
if (securityChaosService.isInjectionActive()) {
List<Product> raw = productRepository.slowSearchFullScan(q); // SQL native non paramétrée
securityChaosService.recordSqlInjection(q, email);
return ResponseEntity.ok(raw);
}
// Fallback N0 : JPQL paramétré sécurisé
return ResponseEntity.ok(productService.searchProducts(...));
OrderController — S2, S4, S5, S8¶
- S2 : dans
getOrder()etgetOrderDetails(), la vérificationorder.getUser().getId().equals(userId)est court-circuitée en N1+ avec log cross-user si détecté - S4 : dans
createOrder(), l'adresse de livraison passe parprocessShippingAddress()en N2+ - S5 : dans
createOrder(), siunitPriceest présent dans le body, il est injecté via la clé_chaosClientPricedansOrderService - S8 : nouvel endpoint
GET /api/orders/{id}/invoice— validé en N0-2, path traversal simulé en N3+
OrderService — S5¶
Object chaosPrice = rawItem.get("_chaosClientPrice");
if (chaosPrice instanceof BigDecimal cp) basePrice = cp;
// → prix client accepté sans revalidation
UserController — S3, S9¶
- S3 :
getProfile()appellebuildProfileDtoWithHash()en N1+ — copie du DTO standard avec ajout du champpassword(hash BCrypt$2a$...) - S9 :
updateProfile()bypasse la whitelist en N3+ viadetectAndRecordMassAssignment(), appliqueemailetpassworddirectement
AuthController — S6, S7¶
- S6 : mesure
System.currentTimeMillis()avant/aprèsauthService.login()+recordTimingAttack()en N2+ - S7 :
generateWeakToken(user.getId())→ headerX-Debug-Tokendans la réponse de login en N3+
ChaosController — reset global¶
resetAll() appelle securityChaosService.reset() — le bouton "Reset tout" du
chaos-admin couvre désormais les 5 systèmes chaos.
4. UI chaos-admin — onglet Chaos Sécurité¶
Temps : ~45 min Difficulté : ⭐⭐⭐
Extension du chaos-admin/public/index.html :
- Tab
🔒 Chaos Sécurité+ section dédiée - 4 cartes de niveau cliquables (0 Désactivé → 3 Expert) avec couleur et description pédagogique
- Bandeau statut : niveau actif + compteur total d'événements de sécurité
- Description courte de chaque faille active par niveau
loadSecurityStatus()appelé au switch d'onglet
5. Monitoring — onglet Sécurité¶
Temps : ~1h Difficulté : ⭐⭐⭐
Extension du monitoring/public/index.html :
- Tab
🔐 Chaos Sécurité - Bandeau niveau actif + compteurs hits globaux
- Grille KPI 9 cases (S1-S9) : compteur de déclenchements + état actif/inactif selon niveau
- Grille failles actives/inactives avec badge sévérité (Junior/Confirmé/Expert)
- Table logs sécurité : 60 dernières entrées, colonnes timestamp/faille/sévérité/utilisateur/détail
fetchSecurity()toutes les 2 secondes
6. Cinq passes de revue de code¶
Temps : ~2h Difficulté : ⭐⭐⭐
Revue exhaustive après chaque bloc d'implémentation majeur. Deux bugs corrigés :
Bug #1 — fetchSecurity() : garde paused incorrecte (revue 3)¶
La fonction utilisait if (paused) au lieu de if (!autoRefresh) — cohérence
avec le pattern des autres onglets (fetchMetier, fetchScripting).
Bug #2 — Accolade fermante parasite dans fetchSecurity() (revue 5)¶
Une accolade } orpheline créait une SyntaxError JavaScript au chargement
de la page — erreur silencieuse côté serveur mais bloquante côté navigateur.
Corrigée via edit_block ciblé.
GO compilation donné après revue 5.
🎢 Chronologie Détaillée¶
Phase 1 (~2h) : SecurityChaosService + Controller 🟢¶
- Définition des 9 flags et compteurs
- Implémentation des méthodes utilitaires S1-S9
- Token HMAC S7 via
javax.crypto.Mac - Pattern PathTraversalResult et WeakTokenValidation (Java 17 records)
- Ressenti : 🟢 Architecture très proche du Chaos Métier — copier/adapter, pas créer
Phase 2 (~2h) : Modifications des 7 controllers/services 🟢¶
- ProductController S1
- OrderController S2, S4, S5, S8
- OrderService S5
- UserController S3, S9
- AuthController S6, S7
- ChaosController reset global
- Ressenti : 🟢 Chaque hook isolé, niveau 0 toujours nominal
Phase 3 (~1h45) : UI chaos-admin + monitoring 🟢¶
- Section chaos-admin : 4 cartes de niveau
- Onglet monitoring : KPIs + logs sécurité
- CSS dédié :
.sec-kpi-grid,.sec-fault,.sec-log-table, badges sévérité - Ressenti : 🟢 Cohérence visuelle avec les onglets Métier et Scripting
Phase 4 (~2h) : 5 passes de revue de code 🟢¶
- Revues 1-2 : aucun problème
- Revue 3 : garde
pausedvs!autoRefresh - Revue 5 : accolade orpheline
SyntaxError - Compilation Maven : 47 sources, BUILD SUCCESS sur le code Java
- Ressenti : 🟢 Confiance haute, peu d'erreurs, revue efficace
🧠 Moments Clés d'Apprentissage¶
1. Zéro dépendance Maven externe grâce au JDK natif¶
HMAC-SHA256 via javax.crypto.Mac et java.util.Base64 disponibles dans tout JDK 8+.
Pas besoin de librairie externe pour les opérations cryptographiques usuelles.
Règle : avant d'ajouter une dépendance Maven, vérifier si le JDK standard couvre
déjà le besoin (java.security, javax.crypto, java.util.Base64).
2. Java 17 records pour les types de retour complexes¶
PathTraversalResult et WeakTokenValidation encapsulent proprement plusieurs valeurs
de retour sans créer des classes entières. Plus lisible qu'un Map<String, Object>,
plus léger qu'un DTO classique.
3. S8 simulé = pédagogie sans risque¶
Simuler le contenu d'un path traversal (/etc/passwd, application.yml) sans accéder
au filesystem réel permet :
- De montrer l'impact d'un vrai LFI (Local File Inclusion) avec du contenu réaliste
- D'éviter tout accès non autorisé au système de fichiers du container
- De maîtriser exactement ce que l'étudiant voit (contenu fictif maîtrisé)
4. Le pattern "hook conditionnel" est scalable¶
La même architecture s'applique sur 4 systèmes chaos (Backend sliders, Scripting tokens, Métier anomalies, Sécurité failles) : service central + méthodes utilitaires + hooks conditionnels dans les controllers existants + endpoints publics pour le monitoring.
5. La revue de code sur le JavaScript est plus délicate qu'en Java¶
Les erreurs JS comme l'accolade orpheline (bug #2) ne lèvent aucune erreur côté serveur —
le fichier est servi, le navigateur échoue silencieusement (ou affiche une SyntaxError
dans la console DevTools). En Java, le compilateur Maven refuse de produire le .jar.
Règle : toujours tester les pages modifiées dans le navigateur après chaque changement JS, DevTools console ouverte.
📊 Métriques de la Session¶
| Métrique | Valeur |
|---|---|
| Durée totale | ~8 heures |
| Conversations Claude | 3 |
| Fichiers Java créés | 2 (SecurityChaosService, SecurityChaosController) |
| Fichiers Java modifiés | 5 (ProductController, OrderController, OrderService, UserController, AuthController, ChaosController) |
| Fichiers HTML modifiés | 2 (chaos-admin/index.html, monitoring/index.html) |
| Failles implémentées | 9 (S1-S9) |
| Passes de revue de code | 5 |
| Bugs corrigés en revue | 2 |
| Sources Maven compilées | 47 (sans erreur) |
| Lignes de code | ~1200 (Java + HTML + JS) |
🎯 Difficultés Rencontrées¶
🟢 Faible (⭐⭐)¶
Problème : role ciblé en S9 mais absent de l'entité User
Temps perdu : ~5 min
Solution : Cible email + password uniquement — fidèle au modèle de données réel
Leçon : Toujours vérifier l'entité JPA avant de cibler un champ en mass assignment
🟢 Faible (⭐⭐)¶
Problème : Bug JS accolade orpheline — SyntaxError silencieux côté serveur
Temps perdu : ~10 min (détecté en revue 5)
Solution : edit_block ciblé sur l'accolade parasite
Leçon : Tester le JS dans le navigateur après chaque modification, DevTools console ouverte
✅ Ce Qui a Bien Fonctionné¶
Architecture mature — copier/adapter, pas créer¶
La Session 8 a bénéficié de toutes les décisions architecturales précédentes.
SecurityChaosService est une variante de BusinessChaosService — même ring buffer,
mêmes patterns, même philosophie. Le temps de conception architecturale était quasi nul.
HMAC sans dépendance externe¶
javax.crypto.Mac + java.util.Base64 suffisent pour HMAC-SHA256. Contrainte "zéro
dépendance Maven" respectée à 100% malgré la complexité du token S7.
Ratio de bugs le plus bas du projet¶
5 passes de revue de code n'ont révélé que 2 bugs, tous mineurs (JS). C'est le meilleur ratio depuis le début du projet — signe d'une architecture maîtrisée et d'une méthodologie de développement rodée.
Compilation Maven propre¶
47 sources compilées sans erreur Java. Le warning unchecked sur OrderController
(cast générique) est intentionnel et documenté. Aucune régression sur le code existant.
🎓 Conclusion¶
Cette session de ~8 heures en vibe coding a permis de :
✅ Implémenter le Chaos Sécurité complet — 9 failles OWASP sur 3 niveaux, toutes observables
✅ Zéro dépendance Maven externe — HMAC-SHA256 via JDK natif, token forgeable pédagogiquement
✅ S8 path traversal simulé — contenu fictif réaliste sans accès filesystem réel
✅ 5 passes de revue de code — 2 bugs détectés et corrigés, compilation Maven propre
✅ Documentation MkDocs complète — chaos/security.md + mise à jour intro, roadmap, guides, index
Ratio temps productif / temps total : ~94% Objectifs atteints : 100% — les 5 systèmes chaos (Backend, Frontend, Scripting, Métier, Sécurité) sont opérationnels
La Session 8 est la session la plus productive du projet en ratio. La maturité architecturale accumulée sur 7 sessions s'est pleinement exprimée : les hooks conditionnels, les ring buffers, les endpoints publics pour le monitoring, les cartes de niveau dans le chaos-admin — tout était déjà là. Il ne restait qu'à le décliner pour la cinquième couche chaos.
La leçon de cette session : investir du temps en architecture propre et en patterns réutilisables sur les premières sessions se rembourse exponentiellement sur les sessions suivantes. La Session 1 a coûté ~3h15 en erreurs pour ~6h de travail (46%). La Session 8 n'a coûté que ~30 min en erreurs pour ~8h de travail (94%).
🤖 Erreurs imputables à Claude AI — Session 8¶
❌ Erreur S8-1 — Garde paused au lieu de !autoRefresh dans fetchSecurity()¶
Ce que j'ai proposé : Le monitoring fetchSecurity() utilisait if (paused) pour
gérer la pause du refresh automatique.
Ce qui s'est passé : Le pattern établi dans les autres onglets (fetchMetier, fetchScripting)
utilise if (!autoRefresh). La variable paused n'existe pas dans ce contexte —
l'onglet sécurité ne se mettait jamais en pause réellement.
Pourquoi c'était une erreur : Incohérence avec la convention établie depuis la Session 6.
J'aurais dû relire les fonctions fetchMetier() et fetchScripting() avant d'écrire
fetchSecurity() pour reprendre exactement le même pattern.
Temps perdu : ~10 min (détecté revue 3) | Sévérité : ⭐⭐
❌ Erreur S8-2 — Accolade fermante orpheline dans fetchSecurity()¶
Ce que j'ai proposé : La fonction fetchSecurity() avec une accolade } parasite
en fin de bloc try/catch.
Ce qui s'est passé : SyntaxError JavaScript bloquant le chargement complet de la
page monitoring — aucun onglet ne se chargeait, erreur visible uniquement dans la console
DevTools.
Pourquoi c'était une erreur : Faute de frappe/décompte classique dans un bloc try/catch imbriqué. La revue de code humaine manuelle (sans linter) ne détecte pas toujours ce type d'erreur au premier coup d'œil sur 50+ lignes de JS.
Temps perdu : ~15 min (détecté revue 5, edit_block ciblé) | Sévérité : ⭐⭐⭐
📊 Récapitulatif Session 8¶
| # | Erreur | Temps perdu | Sévérité |
|---|---|---|---|
| S8-1 | Garde paused vs !autoRefresh dans fetchSecurity() |
~10 min | ⭐⭐ |
| S8-2 | Accolade orpheline — SyntaxError JS | ~15 min | ⭐⭐⭐ |
| TOTAL | ~25 min |
Pattern : Incohérence de convention JS — le même type d'erreur que les bugs CSS chips en Session 7 (chip-PROMO_OK vs chip-PROMO). La frontière compilateur/interpréteur reste le principal angle mort : Java refuse de compiler, JS échoue silencieusement côté serveur.
Progrès notable : 2 bugs en 5 passes de revue sur ~8h de développement — le ratio erreurs/code le plus faible de toutes les sessions. La maturité architecturale du projet se traduit directement en qualité de livraison.