L'origine qu'il croyait sûre : un reflet CORS avec credentials
Le défi
L'API de compte de Halcyon répond aux requêtes du navigateur depuis sa propre application web, et pour que ça fonctionne sur plusieurs domaines, l'équipe a laissé le serveur décider à chaque requête. Il lit l'en-tête Origin envoyé par le navigateur et, s'il ressemble à l'un des leurs, le renvoie tel quel comme origine autorisée en indiquant que les credentials sont acceptés. La page d'un attaquant peut envoyer l'Origin qu'elle veut. Remplace l'Origin par le site de l'attaquant et lis ce que l'API lui renvoie.
Ce que tu vas apprendre
- Expliquer ce que font ensemble Access-Control-Allow-Origin et -Allow-Credentials
- Reconnaître qu'un Origin arbitraire reflété avec des credentials revient à autoriser tous les sites
- Reproduire la lecture en envoyant un Origin d'attaquant
- Expliquer pourquoi le navigateur laisse alors la page de l'attaquant lire la réponse
- Énoncer le correctif par liste d'autorisation et l'interdiction du wildcard avec credentials
Compétences testées
Prérequis
- La same-origin policy dans les grandes lignes
- Ce qu'est l'en-tête Origin
Comment ça marche
CORS permet à un serveur d'autoriser certaines origines tierces à lire ses réponses. Le serveur nomme une origine autorisée dans Access-Control-Allow-Origin, et peut ajouter Access-Control-Allow-Credentials: true pour permettre les cookies. Le navigateur applique ce que le serveur indique.
ReflGéter l'Origin de la requête telle quelle dans cet en-tête, en autorisant en plus les credentials, indique au navigateur que n'importe quel site à l'origine de la requête peut lire la réponse avec les cookies de la victime. Cela couvre toutes les origines, ce que la règle explicite interdisant Allow-Origin: * avec credentials devait justement empêcher ; le reflet contourne la règle tout en ayant le même effet.
Une victime connectée qui visite la page de l'attaquant déclenche une requête avec credentials, et le script de l'attaquant est autorisé à lire le corps privé.
Erreurs fréquentes
- Laisser l'origine réelle de l'application. Cela fonctionne aussi, mais l'enjeu est qu'un site que vous contrôlez soit lui aussi accepté.
- Retirer le cookie. Sans la session de la victime, l'API renvoie 401 ; l'attaque repose sur le fait que le navigateur l'ajoute automatiquement.
- Répondre avec la valeur d'un en-tête. Ce qui compte, ce sont les données du compte dans le corps, en particulier l'email.
- Croire que la same-origin policy protège ce cas. Le serveur l'a explicitement levée en reflétant l'origine et en autorisant les credentials.
Comment s'en protéger
Validez l'origine ; ne la reflétez jamais aveuglément avec des credentials.
- Comparez
Originà une liste d'autorisation stricte et ne renvoyez qu'une valeur connue qui correspond. - N'associez jamais
Access-Control-Allow-Credentials: trueà une origine reflétée ou à un wildcard. - Gardez les lectures sensibles derrière une autorisation qui ne repose pas sur la same-origin policy du navigateur, et restreignez strictement la portée des cookies.