Le partage de ressources d'origine croisée est un mécanisme qui permet à une page Web de faire XMLHttpRequests vers un autre domaine (à partir de wikipedia ).
Je bidouille avec CORS depuis quelques jours et je pense que je comprends assez bien comment tout fonctionne.
Donc, ma question n'est pas sur le fonctionnement de CORS / preflight, mais sur la raison derrière la création de preflights comme nouveau type de demande . Je ne vois aucune raison pour laquelle le serveur A doit envoyer un contrôle en amont (PR) au serveur B juste pour savoir si la vraie demande (RR) sera acceptée ou non - il serait certainement possible pour B d'accepter / rejeter RR sans tout PR précédent.
Après avoir cherché un peu, j'ai trouvé cette information sur www.w3.org (7.1.5):
Pour protéger les ressources contre les demandes d'origine croisée qui ne pouvaient pas provenir de certains agents utilisateurs avant que cette spécification n'existe, une demande de contrôle en amont est effectuée pour s'assurer que la ressource est au courant de cette spécification.
Je trouve que c'est la phrase la plus difficile à comprendre de tous les temps. Mon interprétation (devrait mieux l'appeler «meilleure estimation») est qu'il s'agit de protéger le serveur B contre les demandes du serveur C qui n'est pas au courant de la spécification.
Quelqu'un peut-il expliquer un scénario / montrer un problème que PR + RR résout mieux que RR seul?
Quelle était la motivation derrière l'introduction des demandes de contrôle en amont?
Des demandes de contrôle en amont ont été introduites afin qu'un navigateur puisse être sûr qu'il traite avec un serveur compatible CORS avant d'envoyer certaines demandes. Ces demandes ont été définies comme étant à la fois potentiellement dangereuses (à changement d'état) et nouvelles (non possibles avant CORS en raison de la même politique d'origine ). L'utilisation de demandes de contrôle en amont signifie que les serveurs doivent accepter (en répondant correctement au contrôle en amont) les nouveaux types de demandes potentiellement dangereux que CORS rend possibles.
C'est le sens de cette partie de la spécification : "Pour protéger les ressources contre les demandes d'origine croisée qui ne pouvaient pas provenir de certains agents utilisateurs avant que cette spécification n'existe, une demande de contrôle en amont est effectuée pour s'assurer que la ressource est au courant de cette spécification."
Peux-tu me donner un exemple?
Imaginons qu'un utilisateur de navigateur soit connecté à son site bancaire à l'adresse
A.com
. Lorsqu'ils accèdent au malwareB.com
, cette page contient du Javascript qui essaie d'envoyer uneDELETE
demande àA.com/account
. Étant donné que l'utilisateur est connectéA.com
, cette demande, si elle est envoyée, comprendrait des cookies qui identifient l'utilisateur.Avant CORS, la même politique d'origine du navigateur l'aurait empêché d'envoyer cette demande. Mais comme le but de CORS est de rendre possible ce type de communication entre origines, ce n'est plus approprié.
Le navigateur peut simplement envoyer le
DELETE
fichier et laisser le serveur décider comment le gérer. Mais que faire siA.com
vous n'êtes pas au courant du protocole CORS? Il pourrait aller de l'avant et exécuter le dangereuxDELETE
. Il aurait pu supposer que - en raison de la même politique d'origine du navigateur - il ne pourrait jamais recevoir une telle demande, et donc il n'aurait peut-être jamais été renforcé contre une telle attaque.Pour protéger de tels serveurs non compatibles CORS, le protocole nécessite alors que le navigateur envoie d'abord une demande de contrôle en amont . Ce nouveau type de demande est quelque chose auquel seuls les serveurs compatibles CORS peuvent répondre correctement, permettant au navigateur de savoir s'il est sûr ou non d'envoyer les données réelles
DELETE
.Pourquoi tout ce tapage sur le navigateur, l'attaquant ne peut-il pas simplement envoyer une
DELETE
demande depuis son propre ordinateur?Bien sûr, mais une telle demande n'inclura pas les cookies de l'utilisateur. L'attaque que cela est conçu pour empêcher repose sur le fait que le navigateur enverra des cookies (en particulier, des informations d'authentification pour l'utilisateur) pour l'autre domaine avec la demande.
Cela sonne comme Cross-Site Request Forgery , où une forme sur place
B.com
peutPOST
àA.com
avec les cookies de l'utilisateur et faire des dégâts.C'est vrai. Une autre façon de dire cela est que les demandes de contrôle en amont ont été créées afin de ne pas augmenter la surface d'attaque CSRF pour les serveurs non compatibles CORS.
Mais en regardant les exigences pour les demandes "simples" qui ne nécessitent pas de contrôle en amont, je vois que cela
POST
est toujours autorisé. Cela peut changer l'état et supprimer des données comme unDELETE
!C'est vrai! CORS ne protège pas votre site contre les attaques CSRF. Là encore, sans CORS, vous n'êtes également pas protégé contre les attaques CSRF. Le but des demandes de contrôle en amont est simplement de limiter votre exposition CSRF à ce qui existait déjà dans le monde pré-CORS.
Soupir. OK, j'accepte à contrecœur le besoin de demandes de contrôle en amont. Mais pourquoi devons-nous le faire pour chaque ressource (URL) sur le serveur? Le serveur gère CORS ou non.
Êtes-vous sûr de cela? Il n'est pas rare que plusieurs serveurs gèrent les demandes d'un seul domaine. Par exemple, il peut arriver que les demandes
A.com/url1
soient traitées par un type de serveur et que les demandesA.com/url2
soient traitées par un autre type de serveur. Ce n'est généralement pas le cas que le serveur qui gère une seule ressource peut garantir la sécurité de toutes les ressources de ce domaine.Bien. Faisons un compromis. Créons un nouvel en-tête CORS qui permet au serveur d'indiquer exactement de quelles ressources il peut parler, afin d'éviter des demandes de contrôle en amont supplémentaires à ces URL.
Bonne idée! En fait, l'en-tête a
Access-Control-Policy-Path
été proposé à cette fin. En fin de compte, cependant, elle a été laissée en dehors de la spécification, apparemment parce que certains serveurs ont incorrectement implémenté la spécification URI de telle manière que les requêtes vers des chemins qui semblaient sûrs pour le navigateur ne seraient en fait pas sûres sur les serveurs cassés.Était-ce une décision prudente qui privilégiait la sécurité aux performances, permettant aux navigateurs de mettre immédiatement en œuvre la spécification CORS sans mettre en danger les serveurs existants? Ou était-ce à courte vue de condamner Internet à une bande passante gaspillée et à une latence doublée juste pour accueillir des bogues dans un serveur particulier à un moment particulier?
Les opinions diffèrent.
Eh bien, à tout le moins, les navigateurs mettront en cache le contrôle en amont pour une seule URL?
Oui. Mais probablement pas pour très longtemps. Dans les navigateurs WebKit, la durée maximale du cache de contrôle en amont est actuellement de 10 minutes .
Soupir. Eh bien, si je sais que mes serveurs sont compatibles CORS et n'ont donc pas besoin de la protection offerte par les demandes de contrôle en amont, est-il possible de les éviter?
Votre seule véritable option est de vous assurer que vous répondez aux exigences des demandes "simples". Cela pourrait signifier laisser de côté les en-têtes personnalisés que vous auriez autrement inclus (comme
X-Requested-With
), mentir sur leContent-Type
, ou plus.Quoi que vous fassiez, vous devez vous assurer que vous disposez de protections CSRF appropriées, car la spécification CORS ne traite pas du rejet des demandes "simples", y compris les demandes non sécurisées
POST
. Comme le dit la spécification : "les ressources pour lesquelles les requêtes simples ont une signification autre que la récupération doivent se protéger contre la contrefaçon de requêtes intersites".la source
Considérez le monde des demandes interdomaines avant CORS. Vous pouvez faire un POST de formulaire standard, ou utiliser un
script
ou unimage
tag pour émettre une demande GET. Vous ne pouviez pas faire d'autre type de demande que GET / POST et vous ne pouviez pas émettre d'en-tête personnalisé sur ces demandes.Avec l'avènement de CORS, les auteurs de la spécification ont été confrontés au défi d'introduire un nouveau mécanisme interdomaines sans rompre la sémantique existante du Web. Ils ont choisi de le faire en donnant aux serveurs un moyen d'activer tout nouveau type de demande. Cet opt-in est la demande de contrôle en amont.
Les requêtes GET / POST sans en-têtes personnalisés n'ont donc pas besoin d'un contrôle en amont, car ces requêtes étaient déjà possibles avant CORS. Mais toute demande avec les en- têtes personnalisés, ou des demandes PUT / DELETE, faire ont besoin d' un contrôle en amont, puisque ceux - ci sont nouveaux à la spécification CORS. Si le serveur ne sait rien de CORS, il répondra sans en-têtes spécifiques à CORS et la demande réelle ne sera pas effectuée.
Sans la demande de contrôle en amont, les serveurs pourraient commencer à voir des demandes inattendues de navigateurs. Cela pourrait entraîner un problème de sécurité si les serveurs n'étaient pas préparés pour ce type de demandes. Le contrôle en amont CORS permet aux requêtes interdomaines d'être introduites sur le Web en toute sécurité.
la source
CORS vous permet de spécifier plus d'en-têtes et de types de méthodes qu'il n'était possible auparavant avec l'origine croisée
<img src>
ou<form action>
.Certains serveurs auraient pu être (mal) protégés avec l'hypothèse qu'un navigateur ne peut pas faire, par exemple, une
DELETE
demande d' origine croisée ou une demande d' origine croisée avec en-X-Requested-With
tête, de sorte que ces demandes sont «approuvées».Pour vous assurer que le serveur prend vraiment en charge CORS et ne répond pas simplement aux demandes aléatoires, le contrôle en amont est exécuté.
la source
Voici une autre façon de voir les choses en utilisant du code:
Avant CORS, la tentative d'exploitation ci-dessus échouerait car elle violerait la politique de même origine. Une API conçue de cette façon n'avait pas besoin de protection XSRF, car elle était protégée par le modèle de sécurité natif du navigateur. Il était impossible pour un navigateur pré-CORS de générer un POST JSON d'origine croisée.
Maintenant, CORS entre en scène - si l'adhésion à CORS via le pré-vol n'était pas nécessaire, ce site aurait soudain une vulnérabilité énorme, sans aucune faute de leur part.
Pour expliquer pourquoi certaines demandes sont autorisées à sauter le pré-vol, ceci est répondu par la spécification:
Pour démêler cela, GET n'est pas pré-volé car c'est une "méthode simple" telle que définie par 7.1.5. (Les en-têtes doivent également être "simples" afin d'éviter le pré-vol). La justification de ceci est que la "simple" demande GET d'origine croisée pourrait déjà être effectuée par exemple
<script src="">
(c'est ainsi que fonctionne JSONP). Étant donné que tout élément avec unsrc
attribut peut déclencher un GET d'origine croisée, sans pré-vol, il n'y aurait aucun avantage en termes de sécurité à exiger un pré-combat sur des XHR "simples".la source
Je pense que les autres réponses ne se concentrent pas sur la raison pour laquelle le pré-combat améliore la sécurité.
Scénarios:
1) Avec pré-vol . Un attaquant falsifie une demande du site dummy-forums.com tandis que l'utilisateur est authentifié sur safe-bank.com
Si le serveur ne vérifie pas l'origine et a en quelque sorte un défaut, le navigateur émettra une demande de pré-vol, OPTION méthode. Le serveur ne sait rien de ce CORS que le navigateur attend comme réponse, de sorte que le navigateur ne procédera pas (aucun mal que ce soit)
2) Sans pré-vol . Un attaquant falsifie la demande dans le même scénario que ci-dessus, le navigateur émet immédiatement la demande POST ou PUT, le serveur l'accepte et peut la traiter, cela peut potentiellement causer des dommages.
Si l'attaquant envoie une demande directement, d'origine croisée, à partir d'un hôte aléatoire, il est fort probable que l'on pense à une demande sans authentification. C'est une demande falsifiée, mais pas une demande xsrf. donc le serveur aura vérifier les informations d'identification et échouera. CORS ne tente pas d'empêcher un attaquant disposant des informations d'identification pour émettre des demandes, bien qu'une liste blanche puisse aider à réduire ce vecteur d'attaque.
Le mécanisme de pré-vol ajoute la sécurité et la cohérence entre les clients et les serveurs. Je ne sais pas si cela vaut la poignée de main supplémentaire pour chaque demande, car la mise en cache est robuste, mais c'est ainsi que cela fonctionne.
la source
La source
la source
Les demandes de pré-vol sont nécessaires pour les demandes qui peuvent changer d'état sur le serveur. Il existe 2 types de demandes -
1) Appels qui ne peuvent pas changer d'état sur le serveur (comme GET) - L'utilisateur peut obtenir une réponse pour la demande (si le serveur ne vérifie pas l'origine) mais si le domaine demandeur n'est pas ajouté à l'en-tête de réponse Access-Control- Allow-Origin, le navigateur n'affiche pas les données à l'utilisateur, c'est-à-dire que la demande est envoyée à partir du navigateur mais l'utilisateur n'est pas en mesure d'afficher / d'utiliser la réponse.
2) Appels pouvant changer d'état sur le serveur (comme POST, DELETE) - Depuis en 1), nous voyons que le navigateur ne bloque pas la demande mais la réponse, les appels changeant d'état ne devraient pas être autorisés sans contrôles préalables . De tels appels peuvent apporter des modifications à un serveur de confiance qui ne vérifie pas l'origine des appels (appelé Cross Site Request Forgery), même si la réponse au navigateur peut être un échec. Pour cette raison, nous avons le concept de demandes pré-vol qui effectuent un appel OPTIONS avant que tout appel à changement d'état puisse être envoyé au serveur.
la source
Les demandes de contrôle en amont ne concernent-elles pas les performances ? Avec les demandes de contrôle en amont, un client peut rapidement savoir si l'opération est autorisée avant d'envoyer une grande quantité de données, par exemple en JSON avec la méthode PUT. Ou avant de voyager des données sensibles dans les en-têtes d'authentification sur le fil.
Le fait de PUT, DELETE et d'autres méthodes, en plus des en-têtes personnalisés, ne sont pas autorisés par défaut (ils ont besoin d'une autorisation explicite avec "Access-Control-Request-Methods" et "Access-Control-Request-Headers"), qui sonne tout comme une double vérification, car ces opérations pourraient avoir plus d'implications sur les données utilisateur, à la place des requêtes GET. Cela ressemble donc à:
"J'ai vu que vous autorisez les demandes intersites à partir de http: //foo.example , MAIS êtes-vous SÛR que vous autoriserez les demandes DELETE? Avez-vous pris en compte les impacts que ces demandes pourraient provoquer dans les données utilisateur?"
Je n'ai pas compris la corrélation citée entre les demandes de contrôle en amont et les avantages des anciens serveurs. Un service Web qui a été implémenté avant CORS, ou sans connaissance de CORS, ne recevra jamais de demande intersite, car tout d'abord, leur réponse n'aura pas l'en-tête "Access-Control-Allow-Origin".
la source
Dans un navigateur prenant en charge CORS, les demandes de lecture (comme GET) sont déjà protégées par la même politique d'origine: un site Web malveillant essayant de faire une demande interdomaine authentifiée (par exemple vers le site Web de banque en ligne de la victime ou l'interface de configuration du routeur) ne sera pas pouvoir lire les données renvoyées car la banque ou le routeur ne définit pas l'en-
Access-Control-Allow-Origin
tête.Cependant, avec l' écriture de demandes (comme POST), le dommage est causé lorsque la demande arrive sur le serveur Web. * Un serveur Web pourrait vérifier l'en-
Origin
tête pour déterminer si la demande est légitime, mais cette vérification n'est souvent pas implémentée car le serveur Web n'a pas besoin pour CORS ou le serveur Web est plus ancien que CORS et suppose donc que les POST interdomaines sont complètement interdits par la même politique d'origine.C'est pourquoi les serveurs Web ont la possibilité de choisir de recevoir des demandes d'écriture interdomaines .
* Essentiellement la version AJAX de CSRF.
la source