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 malware B.com
, cette page contient du Javascript qui essaie d'envoyer une DELETE
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 si A.com
vous n'êtes pas au courant du protocole CORS? Il pourrait aller de l'avant et exécuter le dangereux DELETE
. 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
peut POST
à 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 un DELETE
!
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 demandes A.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 le Content-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".