Comment empêcher un code malveillant d'usurper l'en-tête «Origin» pour exploiter CORS?

142

D'après ce que je comprends, si un script côté client s'exécutant sur une page de foo.com veut demander des données à bar.com, dans la demande, il doit spécifier l'en-tête Origin: http://foo.comet la barre doit répondre avec Access-Control-Allow-Origin: http://foo.com.

Qu'y a-t-il pour empêcher le code malveillant du site roh.com d'usurper simplement l'en-tête Origin: http://foo.compour demander des pages à bar?

Jay Lamont
la source
2
Je crois que le fait est que le domaine d'origine à partir duquel la page est servie (ici foo.com) doit fournir l'en- Access-Control-Allow-Origintête, sinon le navigateur n'autorise pas la demande bar.com.
Chris Hayes
2
La lecture de cet article m'a vraiment aidé dans ma compréhension du processus cors entre le navigateur, le serveur d'origine et le serveur cible. html5rocks.com/en/tutorials/cors
brendonparker
5
@ChrisHayes Ce n'est pas du tout la façon dont CORS fonctionne. Vous pouvez lire un peu plus à ce sujet en regardant les spécifications , ou cette superbe page wiki MDN sur le sujet .
Ray Nicholus
1
@brendonparker Oui, c'est un excellent article. Cet auteur répond à de nombreuses questions CORS sur SO, et maintient également enable-cors.org .
Ray Nicholus
4
@RayNicholus Intéressant, j'étais clairement loin. Merci pour les liens. A en juger par les votes sur mon commentaire, je ne suis pas le seul à souffrir de cette illusion. J'espère que ces deux-là reviendront et apprendront (et retireront leurs votes!).
Chris Hayes

Réponses:

149

Les navigateurs contrôlent la définition de l'en- Origintête et les utilisateurs ne peuvent pas remplacer cette valeur. Vous ne verrez donc pas l'en- Origintête usurpé à partir d'un navigateur. Un utilisateur malveillant pourrait créer une requête curl qui définit manuellement l'en- Origintête, mais cette requête proviendrait de l'extérieur d'un navigateur et pourrait ne pas avoir d'informations spécifiques au navigateur (telles que les cookies).

N'oubliez pas: CORS n'est pas la sécurité. Ne comptez pas sur CORS pour sécuriser votre site. Si vous diffusez des données protégées, utilisez des cookies ou des jetons OAuth ou autre chose que l'en- Origintête pour sécuriser ces données. L'en- Access-Control-Allow-Origintête dans CORS dicte uniquement les origines qui doivent être autorisées à faire des demandes d'origine croisée. Ne comptez pas dessus pour rien de plus.

Monsur
la source
3
Cela a beaucoup de sens. Si le navigateur n'autorise pas JavaScript à remplacer l'en-tête Origin, il n'y a aucun problème. Si vous exécutez des demandes depuis l'extérieur du navigateur, vous n'allez pas avoir les cookies. J'imagine que j'étais confus parce que dans tous les documents que je lisais, nulle part il n'était dit explicitement que l'en-tête Origin ne pouvait pas être remplacé. Merci!
Jay Lamont
41
Si quelqu'un veut usurper quelque chose, il peut le faire. En utilisant à peu près n'importe quel langage de script, ils peuvent construire des requêtes http. Perl et Python ont des bibliothèques http qui rendent cela assez facile. Les bibliothèques stockent et envoient des cookies, vous permettent d'ajouter des en-têtes arbitraires et fournissent de nombreuses informations de débogage. Ainsi, les en-têtes CORS sont juste pour rendre plus difficile le javascript malveillant sur un forum que vous lisez pour faire quelque chose de désagréable sur votre compte bancaire sur un autre domaine lorsque vous êtes connecté aux deux dans votre navigateur.
Mnebuerquo
9
Et juste pour clarifier, l'utilisateur malveillant pourrait simplement générer une instance de navigateur qui a été corrigée pour lui permettre de contrôler manuellement l'en-tête Origin, puis se faire passer parfaitement pour un utilisateur normal, des cookies, AJAX et tout.
Jordan Rieger
10
"Les navigateurs contrôlent la définition de l'en-tête Origin et l'utilisateur ne peut pas remplacer cette valeur." Je suis sûr qu'il est très facile d'utiliser un outil comme Fiddler2 ou Charles pour modifier les en-têtes une fois que la demande quitte le navigateur.
Asa
3
l'utilisateur malveillant pourrait simplement générer une instance de navigateur qui a été corrigée pour lui permettre un contrôle manuel sur l'en-tête Origin Si vous avez accès à la machine au point où vous pouvez `` simplement générer une instance de navigateur corrigée '' (cela ne semble pas si simple pour moi), pourquoi ne pas simplement lire directement les cookies du disque? Ils sont stockés en texte brut que vous connaissez. Dans la vraie vie, les scripts intersites sont une réelle menace, alors que votre scénario d'attaque est tout simplement artificiel et peu pratique.
Stijn de Witt
35

TLDR: Rien n'empêche le code malveillant d'usurper l'origine. Lorsque cela se produit, votre serveur ne le saura jamais et agira sur les demandes. Parfois, ces demandes sont coûteuses. N'utilisez donc CORS à la place d'aucun type de sécurité.


J'ai récemment joué avec CORS et je me suis posé la même question. Ce que j'ai trouvé, c'est que le navigateur peut être assez intelligent pour connaître une requête CORS falsifiée lorsqu'il en voit une, mais votre serveur n'est pas aussi intelligent.

La première chose que j'ai trouvée est que l'en- Origintête est un nom d'en-tête HTTP interdit qui ne peut pas être modifié par programme. Ce qui signifie que vous pouvez le modifier en environ 8 secondes en utilisant Modifier les en-têtes pour Google Chrome .

Pour tester cela, j'ai configuré deux domaines clients et un domaine serveur. J'ai inclus une liste blanche CORS sur le serveur, qui a permis les demandes CORS du client 1 mais pas du client 2. J'ai testé les deux clients, et en effet les demandes CORS du client 1 ont réussi tandis que le client 2 a échoué.

Ensuite, j'ai usurpé l'en- Origintête du client 2 pour qu'il corresponde à celui du client 1. Le serveur a reçu l'en- Origintête usurpé et a réussi la vérification de la liste blanche (ou a échoué si vous êtes un type de type verre à moitié vide). Après cela, le serveur a fonctionné consciencieusement en consommant toutes les ressources qu'il était censé consommer (appels à la base de données, envoi d'e-mails coûteux, envoi de messages SMS encore plus chers, etc.). Lorsque cela a été fait, le serveur a volontiers renvoyé l'en- Access-Control-Allow-Origintête usurpé au navigateur.

La documentation que j'ai lue indique que la Access-Control-Allow-Originvaleur reçue doit correspondre Originexactement à la valeur envoyée dans la demande. Ils correspondent, donc j'ai été surpris quand j'ai vu le message suivant dans Chrome:

XMLHttpRequest ne peut pas se charger http://server.dev/test. L'en-tête 'Access-Control-Allow-Origin' a une valeur http://client1.dev qui n'est pas égale à l'origine fournie. Origin http://client2.dev n'est donc pas autorisé à accéder.

La documentation que j'ai lue ne semble pas exacte. L'onglet réseau de Chrome montre clairement à la fois les en-têtes de demande et de réponse http://client1.dev, mais vous pouvez voir dans l'erreur que Chrome sait d'une manière ou d'une autre que l'origine réelle était http://client2.devet rejette correctement la réponse. Ce qui n'a pas d'importance à ce stade, car le serveur avait déjà accepté la demande falsifiée et dépensé mon argent.

Nocturno
la source
2
@Nocturno, merci pour l'exemple. Permettez-moi d'ajouter mon observation. CORS concerne les fonctionnalités de sécurité du navigateur. Si un navigateur sécurisé est modifié à partir de son état d'origine, cela pourrait être interprété comme le navigateur manquant peut-être d'une fonction de sécurité.
Luka Žitnik
10
Pas génial du tout. Il manque complètement le point de CORS. Si vous êtes en mesure d'intercepter les requêtes provenant de la machine de l'utilisateur, vous pouvez simplement lire leurs cookies, installer des enregistreurs de frappe, des virus et toutes ces autres menaces réelles. CORS est là pour protéger les utilisateurs honnêtes connectés au site A d'un script malveillant qui a été injecté d'une manière ou d'une autre sur le site B.Le script du site B (qui pourrait être un extrait de Javascript dans un message de forum qui n'a pas été correctement échappé par le site B) actions sur le site A sous le compte de l'utilisateur (par exemple, supprimer des éléments, etc.), en utilisant le cookie de session du site A.
Stijn de Witt
3
Cela s'appelle des scripts intersites et sans CORS, cela pourrait être fait sans jamais avoir besoin de prendre le contrôle de la machine de l'utilisateur. Exactement. Aucun contrôle sur la machine de l'utilisateur n'était nécessaire car lors de la demande au site A, le navigateur utilisait pour ajouter automatiquement le cookie de session à la demande, de sorte qu'il ressemblait à une demande valide de l'utilisateur lui-même alors qu'en fait il provenait d'un script sur un autre site. La politique de même origine l'empêche et CORS est utilisé pour mettre sur liste blanche les domaines auxquels l'accès doit être accordé même s'ils sont sur une origine différente.
Stijn de Witt
3
@Nocturno Ouais j'étais peut-être un peu trop grossier, désolé pour ça. Votre point d'origine tient. La politique de même origine est une fonctionnalité de sécurité du navigateur et CORS est un mécanisme pour affaiblir cette sécurité en ajoutant certains domaines à la liste blanche. OP doit comprendre que l'usurpation de l'en-tête Origin n'est pas vraiment viable en tant qu'attaque car elle ne vous apporte rien qui ne peut pas être obtenu avec, par exemple, curl.
Stijn de Witt
3
@Nocturno Je pense que votre déclaration liminaire est un peu trompeuse. There's nothing stopping malicious code from spoofing the origin-> Oui, javascript ne peut pas être défini Origin. Oui, un utilisateur peut modifier son navigateur / utiliser un violoneux pour changer l'origine, mais ce n'est pas ce contre quoi CORS se défend; Les sites Web contrôlés par des attaquants ne peuvent pas modifier l'origine, c'est tout ce qui compte.
RJFalconer
13

Juste un humble résumé:

Q: La politique de même origine (SOP) est-elle appliquée uniquement par les navigateurs?
R: Oui. Pour tous les appels que vous effectuez dans un navigateur, le SOP est définitivement appliqué par le navigateur. Le serveur peut ou non vérifier l'origine de la demande.

Q: Si une demande n'est pas conforme aux SOP, le navigateur la bloque-t-elle?
R: Non, cela dépasse l'autorité des navigateurs. Les navigateurs envoient simplement des requêtes d'origine croisée et attendent la réponse pour voir si l'appel est signalé légitime par le serveur via les en Access-Control-têtes - *. Si le serveur ne renvoie pas l'en- Access-Control-Allow-Origintête, ne renvoie pas l'origine de l'appelant ou ne renvoie pas l' *en-tête, alors tout ce qu'un navigateur fera est de s'abstenir de fournir la réponse à l'appelant.

Q: Cela signifie-t-il que je ne peux pas usurper Origin?
R: Dans le navigateur et à l'aide de scripts, vous ne pouvez pas remplacer Origincar il est sous le contrôle du navigateur. Cependant, si vous souhaitez vous pirater, vous pouvez falsifier les appels sortant de VOTRE navigateur à l'aide d'extensions de navigateur ou d'autres outils que vous installez sur votre machine. Vous pouvez également émettre des HTTPappels à l' aide curl, Python, C#, etc et modifier l' en- Origintête pour les serveurs trick.

Q: Donc, si je peux tromper le serveur en le modifiant Origin, cela signifie-t-il qu'il CORSn'est pas sécurisé?
R: en CORS soi, il est silencieux sur la sécurité - c'est-à-dire l'authentification et l'autorisation des demandes. C'est aux serveurs d'inspecter les demandes et de les authentifier / les autoriser par tout mécanisme avec lequel ils travaillent, comme les cookies et les en-têtes. Cela dit, cela peut nous protéger un peu plus en cas d'attaques comme XSS:

Exemple: disons que vous vous êtes connecté à votre site Web et qu'un script malveillant tente d'envoyer une requête au site Web de votre banque pour demander votre solde: une attaque Reflected XSS . Le site Web de votre banque fait confiance aux informations d'identification provenant de (ici au nom de) votre site Web afin que la demande soit authentifiée et qu'une HTTPréponse visant le code malveillant soit émise. Si le site Web de votre banque ne se soucie pas de partager ses points de terminaison avec d'autres origines, il n'inclut pasAccess-Control-Allow-Originen-tête dans la réponse. Désormais, à l'arrivée de la requête, le navigateur se rend compte que la requête était une requête Cross Origins, mais la réponse ne montre pas que le serveur était heureux de partager la ressource (ici le point de terminaison de la requête d'équilibre) avec votre site Web. Donc, cela brise le flux, donc le résultat retourné n'atteindra jamais le code malveillant.

Alireza
la source
Bien, meilleur / plus clair que la réponse acceptée IMO
3dGrabber