Révisions — OWASP Top 10 2025
Résumé du module
L’OWASP Top 10:2025 classe les risques web en 10 catégories, de A01 Broken Access Control à A10 Mishandling of Exceptional Conditions (deux nouveautés 2025 : A03 Supply Chain et A10). Chaque faille se lit en 4 temps : exploitation, code vulnérable, correction, lab. Fil rouge : ne jamais faire confiance à une entrée contrôlée par le client.
Séances sources : 2026-11-02 — Contrôle d’accès et mauvaises configurations · 2026-11-03 — Dépendances, crypto et injection · 2026-11-04 — Design, authentification et robustesse
🗂️ Le classement
A01 (OWASP 2025)
Broken Access Control
A02 (OWASP 2025)
Security Misconfiguration
A03 (OWASP 2025)
Software Supply Chain Failures (nouveau 2025)
A04 (OWASP 2025)
Cryptographic Failures
A05 (OWASP 2025)
Injection
A06 (OWASP 2025)
Insecure Design
A07 (OWASP 2025)
Authentication Failures
A08 (OWASP 2025)
Software or Data Integrity Failures
A09 (OWASP 2025)
Security Logging & Alerting Failures
A10 (OWASP 2025)
Mishandling of Exceptional Conditions (nouveau 2025)
Dans quelle catégorie la SSRF est-elle rangée en 2025 ?
A01 Broken Access Control (fusionnée dans A01)
Quel est le fil rouge du cours ?
Ne jamais faire confiance à une entrée contrôlée par le client
🔐 A01 · Broken Access Control
IDOR
Insecure Direct Object Reference : un identifiant d’objet manipulable permet d’accéder à la ressource d’un autre utilisateur (contrôle d’accès horizontal)
Comment détecte-t-on un IDOR ?
On rejoue la requête en changeant l’ID : 403 attendu, 200 obtenu
Correction d'un IDOR ?
Vérifier la propriété de l’objet (pas seulement l’authentification), idéalement filtrer en base par
ownerId
Mass assignment
Le client envoie un champ sensible (
role,isAdmin) que le serveur recopie aveuglément dans l’objet
Correction du mass assignment ?
Une allowlist des champs modifiables
Élévation de privilèges verticale vs horizontale ?
- Verticale : atteindre une fonction d’un rôle supérieur (admin).
- Horizontale : accéder aux données d’un autre utilisateur de même rôle (IDOR).
Charge typique de path traversal
../../../../etc/passwd
Correction d'un path traversal ?
basename()+ allowlist des fichiers autorisés
SSRF
Server-Side Request Forgery : on fait émettre au serveur une requête vers une cible interne (127.0.0.1, 10.x, métadonnées cloud)
Adresse des métadonnées cloud visée en SSRF ?
169.254.169.254
Contournements de filtre SSRF ?
IP en décimal / octal / hexa, IPv6, redirection, DNS rebinding, autres schémas (
file://,gopher://)
Correction d'une SSRF ?
Résoudre et valider l’hôte avant la requête, bloquer les IP internes, allowlist de domaines, interdire les redirections
Pourquoi le CSRF fonctionne-t-il ?
Le navigateur joint automatiquement le cookie de session à une requête déclenchée par un site tiers
Les 3 défenses anti-CSRF ?
- Jeton anti-CSRF par formulaire, vérifié serveur
- Cookie
SameSite=Lax/Strict- Vérification d’
Origin/Referer
Mauvaise config CORS classique ?
Refléter l’
Originde la requête +Access-Control-Allow-Credentials: true
Peut-on combiner Access-Control-Allow-Origin: * et les credentials ?::Non, jamais : on utilise une allowlist d’origines explicites
⚙️ A02 · Security Misconfiguration
Où se situe une faille A02 ?
Dans la configuration de la stack, pas dans le code métier
Risque d'une application Flask en
debug=Trueen production ?Traceback complet + console de debug interactive exposés
Correction des erreurs verbeuses ?
Debug off, message générique à l’utilisateur, détail journalisé côté serveur
Rôle de HSTS (
Strict-Transport-Security) ?Forcer HTTPS
Rôle de
Content-Security-Policy?Limiter les sources de scripts (défense anti-XSS)
Rôle de X-Content-Type-Options: nosniff ?::Empêcher le MIME sniffing
Rôle de
X-Frame-Options/frame-ancestors?Défense anti-clickjacking
Les 3 attributs de sécurité d'un cookie ?
Secure,HttpOnly,SameSite
Middleware Express qui pose les en-têtes de sécurité ?
helmet
Que permet un
/.git/exposé ?Reconstruire le code source et lire l’historique (secrets supprimés compris)
Désactiver le listing de répertoire ?
nginx
autoindex off;· ApacheOptions -Indexes
XXE
XML External Entity : un parser XML qui résout les entités externes permet de lire des fichiers locaux, scanner le réseau interne ou provoquer un DoS
Charge XXE de lecture de fichier ?
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>puis&xxe;dans le corps
Flags libxml dangereux en PHP ?
LIBXML_NOENTetLIBXML_DTDLOAD
Correction d'une XXE ?
Désactiver DOCTYPE et entités externes ; préférer JSON
📦 A03 · Supply Chain
Dependency confusion
Un paquet interne introuvable est résolu sur le registre public, où l’attaquant a publié un paquet malveillant du même nom
Typosquatting
Publier un paquet au nom proche d’un paquet populaire pour piéger les fautes de frappe
Commande npm qui respecte le lockfile ?
npm ci
Outils d'audit de dépendances ?
npm audit,pip-audit
SBOM
Software Bill of Materials : inventaire des composants (format CycloneDX)
Injection dans un workflow GitHub Actions ?
Une donnée externe (titre d’issue / de PR) interpolée via
${{ }}dans unrun:devient du code shell
Correction d'une injection de workflow ?
Passer la donnée par une variable d’environnement, épingler les actions au SHA, permissions minimales, pas de secrets pour les PR externes
🔑 A04 · Cryptographic Failures
Pourquoi MD5 / SHA1 sont-ils mauvais pour les mots de passe ?
Ils sont rapides : des milliards d’essais par seconde, cassables hors ligne
Algorithmes recommandés pour les mots de passe ?
bcrypt ou argon2id (lents + salés)
Où stocker les secrets ?
Hors du code : variables d’environnement ou coffre à secrets
Exigences de transport ?
HTTPS partout, TLS ≥ 1.2, HSTS
Règle d'or de la crypto ?
La crypto ne s’invente pas : primitives éprouvées, bien configurées
💉 A05 · Injection
Principe de correction unique des injections ?
Séparer les données du code (paramétrage, échappement)
Charge SQLi de login bypass
' OR '1'='1' --
Charge SQLi UNION
' UNION SELECT username,password FROM users --
SQLi aveugle (blind)
On déduit la donnée via des réponses vrai / faux ou le temps de réponse
Correction d'une SQLi ?
Requêtes paramétrées (
prepare+execute), jamais de concaténation
Les 3 types de XSS ?
- Réfléchi : la charge est dans l’URL
- Stocké : la charge est en base, rejouée à chaque visite
- DOM : exécutée côté client (
innerHTML,eval), sans aller-retour serveur
Correction d'une XSS ?
Échapper en sortie selon le contexte + CSP + cookies
HttpOnly; côté clienttextContentau lieu d’innerHTML
Séparateurs utilisés en injection de commandes ?
;|&&et la substitution$(...)
Détecter une injection de commandes aveugle ?
Par un délai (
; sleep 10)
Correction d'une injection de commandes ?
Valider (
FILTER_VALIDATE_IP) +escapeshellarg(), et mieux : éviter le shell
SSTI
Server-Side Template Injection : une entrée concaténée au template est évaluée par le moteur, jusqu’au RCE
Charge de détection SSTI Jinja2 ?
{{7*7}}→ renvoie49
Correction d'une SSTI ?
Passer l’entrée comme variable du template, jamais dans le template lui-même
🧩 A06 · Insecure Design
Spécificité d'une faille A06 ?
C’est un défaut de conception : aucun correctif de ligne ne la règle
TOCTOU
Time Of Check to Time Of Use : deux requêtes simultanées passent le contrôle avant la mise à jour de l’état (double dépense)
Correction d'une condition de course ?
Opération atomique en base (
UPDATE … WHERE balance >= :amt) + verrou / clé d’idempotence + rate limiting
Exemples de contournement de logique métier ?
Sauter l’étape de paiement, appliquer deux fois un code promo, quantité ou prix négatif, rejouer un webhook
Démarche de conception contre les abus ?
Threat modeling dès la conception + tout vérifier côté serveur
👤 A07 · Authentication Failures
Énumération d'utilisateurs
Le serveur répond différemment (message ou temps) selon que le compte existe
Défense contre l'énumération ?
Réponses et temps de réponse identiques (login et reset)
Les deux attaques JWT classiques du cours ?
Accepter
alg: noneet casser un secret HMAC faible
Correction JWT ?
Figer l’algorithme attendu + clé longue et aléatoire (ou RS256) ; vérifier la signature systématiquement
Fixation de session
L’attaquant impose un identifiant de session que la victime garde après s’être connectée
Défense contre la fixation de session ?
Régénérer l’identifiant de session après connexion ; invalider à la déconnexion
Jeton de reset de mot de passe correct ?
Long, aléatoire, à usage unique et expirant ; ne pas se fier à l’en-tête
Host
Comment contourne-t-on une MFA mal faite ?
OTP sans limite de tentatives, ou étape sautable (accès direct à la page suivante)
🧬 A08 · Integrity Failures
Danger de la désérialisation non sûre ?
Instancier des objets arbitraires et exécuter du code à la reconstruction (gadget chains) → RCE
Méthode Python abusée avec pickle ?
__reduce__
Correction d'une désérialisation non sûre ?
Format de données (JSON) ; sinon signer (HMAC) et vérifier, restreindre les classes
Garantir l'intégrité des artefacts et mises à jour ?
Signer et vérifier (Sigstore), verrouiller les dépendances, épingler les actions CI au SHA
📝 A09 · Logging & Alerting
Log injection
Un
\ndans une entrée journalisée forge de fausses lignes de log
Correction de la log injection ?
Logs structurés (JSON), échapper
\ret\n
Que ne faut-il jamais journaliser ?
Mots de passe et jetons
Événements de sécurité à journaliser ?
Échecs d’authentification, accès refusés (+ alerte, corrélation, rétention)
💥 A10 · Exceptional Conditions
Fail-open
En cas d’erreur, l’application accorde l’accès (ex.
catch → allowed = true)
Fail-closed
En cas d’erreur, refus par défaut, erreur journalisée, message générique
Autres défenses A10 ?
Limites de taille et timeouts contre l’épuisement de ressources