Quels sont les risques de sécurité liés à la configuration d'Access-Control-Allow-Origin?

124

J'ai récemment dû configurer Access-Control-Allow-Originpour *pouvoir effectuer des appels ajax entre sous-domaines.
Maintenant, je ne peux pas m'empêcher de penser que je mets mon environnement à des risques de sécurité.
S'il vous plaît, aidez-moi si je fais mal.

Hamed Momeni
la source

Réponses:

69

En répondant avec Access-Control-Allow-Origin: *, la ressource demandée permet le partage avec toutes les origines. Cela signifie essentiellement que n'importe quel site peut envoyer une requête XHR à votre site et accéder à la réponse du serveur, ce qui ne serait pas le cas si vous n'aviez pas implémenté cette réponse CORS.

Ainsi, tout site peut faire une demande à votre site au nom de ses visiteurs et traiter sa réponse. Si vous avez mis en œuvre quelque chose comme un système d'authentification ou d'autorisation basé sur quelque chose qui est automatiquement fourni par le navigateur (cookies, sessions basées sur des cookies, etc.), les demandes déclenchées par les sites tiers les utiliseront également.

Cela pose en effet un risque de sécurité, en particulier si vous autorisez le partage de ressources non seulement pour certaines ressources mais pour chaque ressource. Dans ce contexte, vous devriez jeter un œil à Quand est-il sûr d'activer CORS? .

Gombo
la source
2
Si vous pouvez donner un exemple spécifique de la façon dont l'accès d'authentification partagé pose un risque pour la sécurité, je vais voter pour cela.
Petrus Theron
1
@Gumbo Et le contenu statique? (par exemple, le contenu cdn statique, comme les javascripts, les css, les html statiques, etc.) Y a-t-il des problèmes de sécurité liés Access-Control-Allow-Origin: *à leur paramétrage ? Il n'y aura pas de nogin etc, ils sont publics pour tout le monde?
Umut Benzer
2
@UmutBenzer C'est bon.
Gumbo le
25
En fait, cette réponse n'est pas tout à fait correcte selon la norme CORS actuelle : "La chaîne '*' ne peut pas être utilisée pour une ressource qui prend en charge les informations d'identification." Vous ne pouvez donc pas forcer une demande d'utilisation de l'authentification transitoire sous la forme de cookies, d'authentification HTTP en cache ou de certificats SSL client. Cependant, si le site Web utilisait, par exemple, le stockage local pour l'authentification, ce serait un problème.
Niklas B.
2
@NiklasB: J'ai essayé ce scénario et Chrome suit la norme CORS comme vous l'avez mentionné. c'est-à-dire que la chaîne " " n'est pas prise en charge avec une demande d'informations d'identification. Voici ce qui est rapporté par Chrome: "XMLHttpRequest ne peut pas charger localhost: 12346 / hello . Un caractère générique" "ne peut pas être utilisé dans l'en-tête" Access-Control-Allow-Origin "lorsque l'indicateur d'informations d'identification est vrai. Origin" localhost: 12345 " n'est donc pas autorisé à accéder. Le mode d'identification d'une requête XMLHttpRequest est contrôlé par l'attribut withCredentials. "
factotum
37

Access-Control-Allow-Origin: *peut être ajouté en toute sécurité à n'importe quelle ressource, sauf si cette ressource contient des données privées protégées par autre chose que des informations d'identification standard (cookies, authentification de base, certificats clients TLS).

Par exemple: les données protégées par les cookies sont en sécurité

Imaginez https://example.com/users-private-data, qui peut exposer des données privées en fonction de l'état de connexion de l'utilisateur. Cet état utilise un cookie de session. Il est prudent d'ajouter Access-Control-Allow-Origin: *cette ressource, car cet en-tête ne permet d'accéder à la réponse que si la demande est effectuée sans cookies, et les cookies sont nécessaires pour obtenir les données privées. En conséquence, aucune donnée privée n'est divulguée.

Par exemple: les données protégées par emplacement / ip / réseau interne ne sont pas sûres (malheureusement courantes avec les intranets et les appareils ménagers):

Imaginez https://intranet.example.com/company-private-data, qui expose les données de l'entreprise privée, mais cela n'est accessible que si vous êtes sur le réseau wifi de l'entreprise. Il n'est pas sûr d'ajouter Access-Control-Allow-Origin: *à cette ressource, car elle est protégée par autre chose que les informations d'identification standard. Sinon, un mauvais script pourrait vous utiliser comme tunnel vers l'intranet.

Règle de base

Imaginez ce qu'un utilisateur verrait s'il accédait à la ressource dans une fenêtre de navigation privée. Si vous êtes satisfait que tout le monde voit ce contenu (y compris le code source reçu par le navigateur), vous pouvez l'ajouter en toute sécurité Access-Control-Allow-Origin: *.

JaffaTheCake
la source
devrait "car il n'autorise que les requêtes sans cookies" être "car il n'autorise que les requêtes avec cookies"?
DJCordhose
3
@DJCordhose no. Access-Control-Allow-Origin: *n'autorise que les demandes sans cookies. J'ai édité la réponse pour clarifier un peu.
JaffaTheCake
Quelle est la différence entre "*" et cas sans cet en-tête du tout. Est-ce la même?
Nigrimmist
J'adorerais si «Sinon, un mauvais script pourrait vous utiliser comme un tunnel vers l'intranet» pouvait être expliqué plus en détail.
Sam Rueby
@Nigrimmist Ensuite, la demande de contrôle en amont échouera et l'accès aux ressources sera bloqué
iamareebjamal
9

AFAIK, Access-Control-Allow-Origin est juste un en-tête http envoyé du serveur au navigateur. Le limiter à une adresse spécifique (ou la désactiver) ne rend pas votre site plus sûr, par exemple pour les robots. Si les robots le souhaitent, ils peuvent simplement ignorer l'en-tête. Les navigateurs habituels (Explorer, Chrome, etc.) respectent par défaut l'en-tête. Mais une application comme Postman l' ignore tout simplement.

L'extrémité du serveur ne vérifie pas réellement l'origine de la requête lorsqu'elle renvoie la réponse. Il ajoute simplement l'en-tête http. C'est le navigateur (côté client) qui a envoyé la requête qui décide de lire l'en-tête de contrôle d'accès et d'agir en conséquence. Notez que dans le cas de XHR, il peut utiliser une requête spéciale 'OPTIONS' pour demander les en-têtes en premier.

Ainsi, toute personne ayant des capacités de création de scripts peut facilement ignorer l'en-tête entier, quel que soit celui qui y est défini.

Voir aussi Problèmes de sécurité possibles liés à la configuration d'Access-Control-Allow-Origin .


Maintenant pour répondre à la question

Je ne peux pas m'empêcher de penser que je mets mon environnement à des risques de sécurité.

Si quelqu'un veut vous attaquer, il peut facilement contourner Access-Control-Allow-Origin. Mais en activant «*», vous donnez à l'attaquant quelques «vecteurs d'attaque» supplémentaires avec lesquels jouer, par exemple en utilisant des navigateurs Web normaux qui honorent cet en-tête HTTP.

grand brochet
la source
6
Regardez cela du point de vue d'un utilisateur final imprudent. Quelqu'un peut configurer une page Web malveillante qui injecte du JavaScript pour transmettre des données entre le site réel et un site malveillant (disons qu'il veut voler votre mot de passe). Le navigateur Web de l'utilisateur final bloquera normalement cette communication intersite, mais si le Contrôle d'accès-Autoriser-Origine est défini, il sera alors autorisé et l'utilisateur final ne sera pas plus sage.
Brain2000
3
Oui, la configuration Access-Control-Allow-Origin *sur un site Web malveillant qui héberge des scripts pour voler des mots de passe est fortement déconseillée :-)
commonpike
6
@commonpike Vous avez raison de dire que quelqu'un pourrait créer un script pour ignorer totalement l'en-tête. Si les données sont accessibles, elles sont accessibles avec ou sans en-têtes CORS. Il y a cependant un autre vecteur d'attaque que vous ne considérez pas. Supposons que je me connecte au site Web de ma banque. Si je vais sur une autre page et que je retourne ensuite dans ma banque, je suis toujours connecté à cause d'un cookie. D'autres utilisateurs sur Internet peuvent accéder aux mêmes URL à ma banque que moi, mais ils ne pourront pas accéder à mon compte sans le cookie. Si les demandes d'origine croisée sont autorisées, un site Web malveillant peut effectivement se faire passer pour ...
Brad
5
@commonpike ... l'utilisateur. En d'autres termes, vous pouvez simplement visiter mon site (qui pourrait même être un site normal, sans rien de suspect ... peut-être que c'est un vrai site légitime qui vient d'être détourné!) Mais du JavaScript qui envoie des requêtes HTTP à votre banque pour en transférer fonds sur mon compte. La banque ne connaît pas la différence entre les demandes provenant de ses pages et les demandes provenant d'autres pages. Les deux ont ce cookie permettant à la demande de réussir.
Brad
3
@commonpike Permettez-moi de vous donner un exemple plus courant ... celui qui arrive tout le temps. Supposons que vous ayez un routeur domestique commun, tel qu'un Linksys WRT54g ou autre. Supposons que le routeur autorise les requêtes cross-origin. Un script sur ma page Web pourrait envoyer des requêtes HTTP aux adresses IP communes du routeur (comme 192.168.1.1) et reconfigurer votre routeur pour autoriser les attaques. Il peut même utiliser votre routeur directement comme nœud DDoS. (La plupart des routeurs ont des pages de test qui permettent des pings ou de simples vérifications de serveur HTTP. Celles-ci peuvent être abusées en masse.)
Brad
6

Voici 2 exemples publiés sous forme de commentaires, lorsqu'un caractère générique est vraiment problématique:

Supposons que je me connecte au site Web de ma banque. Si je vais sur une autre page et que je retourne ensuite dans ma banque, je suis toujours connecté à cause d'un cookie. D'autres utilisateurs sur Internet peuvent accéder aux mêmes URL à ma banque que moi, mais ils ne pourront pas accéder à mon compte sans le cookie. Si les demandes d'origine croisée sont autorisées, un site Web malveillant peut effectivement se faire passer pour l'utilisateur.

- Brad

Supposons que vous ayez un routeur domestique commun, tel qu'un Linksys WRT54g ou autre. Supposons que le routeur autorise les requêtes cross-origin. Un script sur ma page Web pourrait envoyer des requêtes HTTP aux adresses IP communes du routeur (comme 192.168.1.1) et reconfigurer votre routeur pour autoriser les attaques. Il peut même utiliser votre routeur directement comme nœud DDoS. (La plupart des routeurs ont des pages de test qui permettent des pings ou de simples vérifications de serveur HTTP. Celles-ci peuvent être abusées en masse.)

- Brad

Je pense que ces commentaires auraient dû être des réponses, car ils expliquent le problème avec un exemple concret.

Christian Gollhardt
la source
8
Sauf que cela ne fonctionnera pas. "La chaîne '*' ne peut pas être utilisée pour une ressource qui prend en charge les informations d'identification." w3.org/TR/cors/#resource-requests
bayo
@bayotop Comment le navigateur fait-il la distinction entre les pages qui nécessitent une authentification et celles avec d'autres données dans les en-têtes?
wedstrom
Après avoir lu le lien fourni, il y a "prend en charge le drapeau des informations d'identification" qui est utilisé à cette fin. Il semble être défini manuellement, donc vraisemblablement si quelqu'un ne savait pas comment configurer correctement CORS, il pourrait également se tromper sur cet indicateur, donc je pense que les vulnérabilités ci-dessus sont possibles.
wedstrom
2
@wedstrom Le drapeau est défini par celui qui fait la demande. Quoi qu'il en soit, les scénarios ci-dessus sont des exemples d'attaques CSRF. Autoriser l'origine '*' ne vous rendra pas plus vulnérable que vous l'êtes déjà (peut-être un peu dans de rares cas). Dans la plupart des cas, vous pouvez faire la demande intersite malveillante à l'aide de formulaires afin que CORS n'ait pas d'importance. Dans les cas où vous devez faire une demande AJAX, les demandes de pré-vol viendront gêner (c'est le point où le navigateur entre en jeu lorsque ACAO: '*' et Access-Control-Allow-Credentials: 'true').
bayo
0

Dans le scénario où le serveur tente de désactiver complètement le CORS en définissant les en-têtes ci-dessous.

  • Access-Control-Allow-Origin: * (indique au navigateur que le serveur accepte les requêtes intersites de toute ORIGINE)

  • Access-Control-Allow-Credentials: true (indique au navigateur que les requêtes intersites peuvent envoyer des cookies)

Il y a une sécurité intégrée implémentée dans les navigateurs qui entraînera une erreur ci-dessous

"Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’"

Ainsi, dans la plupart des scénarios, définir «Access-Control-Allow-Origin» sur *ne sera pas un problème. Cependant, pour se protéger contre les attaques, le serveur peut maintenir une liste des origines autorisées et chaque fois que le serveur reçoit une demande d'origine croisée, il peut valider l'en-tête ORIGIN par rapport à la liste des origines autorisées, puis renvoyer la même chose dans Access-Control-Allow-Origin entête.

Étant donné que l'en-tête ORIGIN ne peut pas être modifié par javascript exécuté sur le navigateur, le site malveillant ne pourra pas l'usurper.

shadow0359
la source