CSRF, SSRF et redirections ouvertes
Trois attaques qui exploitent la confiance : le navigateur fait confiance au site (CSRF), le serveur fait confiance à ses propres requêtes (SSRF), l'utilisateur fait c…
Prérequis : cours précédent ; cookies/SameSite (Réseaux 7.2).
Pourquoi
Trois attaques qui exploitent la confiance : le navigateur fait confiance au site (CSRF), le serveur fait confiance à ses propres requêtes (SSRF), l'utilisateur fait confiance au domaine (redirection ouverte). Trois parades distinctes à connaître.
Concepts
- CSRF : un site malveillant fait exécuter une action sur TON site via le navigateur de la victime (cookies envoyés tout seuls). Parades :
SameSite=Lax/Strict(1ère ligne !), token anti-CSRF sur mutations, vérifierOrigin. - SSRF : le SERVEUR fetch une URL fournie par l'user (
?url=…pour un aperçu) → atteint l'interne (métadonnées cloud169.254.169.254!). Parades : allowlist de domaines, blocage IP privées/réservées, pas de redirects suivis, timeouts. - Redirection ouverte (
/redirect?to=evil.com) : phishing parfait (domaine légitime → site faux). Parade : allowlist de destinations, jamais d'URL arbitraire.
Exemple : tester en 2 minutes
# CSRF : formulaire POST cross-origin sans token → exécuté ? (SameSite absent ?)
# SSRF : ?url=http://169.254.169.254/ → métadonnées cloud ? → faille critique
# Redirect : ?next=https://evil.com → suit ? → allowlist !
Cas réel
SSRF vers 169.254.169.254 sur une app AWS : clés IAM temporaires exfiltrées, puis S3 vidés (données) — $50k de frais + fuite. Correctif : IMDSv2 (token requis) + egress filtré + allowlist. Une URL « pratique » devenue catastrophe.
Pièges
- « GET ne modifie rien donc pas de CSRF » : un GET qui change l'état = vulnérable (et contraire à HTTP). Mutations en POST+token.
- Bloquer
169.254.169.254en string-match : contournements (décimal, octal, redirect, DNS). Parser l'URL, résoudre, vérifier la plage IP. - Redirection « interne » par préfixe (
startsWith('/')) ://evil.compasse (URL protocol-relative !). Parser strict.
À retenir
CSRF = SameSite + token ; SSRF = allowlist + pas d'IP privées + IMDSv2 ; redirect = allowlist stricte.