Si je comprends bien, si un script côté client exécuté sur une page de foo.com veut demander des données à bar.com, il doit spécifier dans la requête l'en-tête Origin: http://foo.com
, et bar doit répondre par Access-Control-Allow-Origin: http://foo.com
.
Qu'est-ce qui empêche les codes malicieux du site roh.com d'usurper l'en-tête Origin: http://foo.com
demander des pages au bar?
Les navigateurs contrôlent la définition de l'en-tête Origin
et les utilisateurs ne peuvent pas remplacer cette valeur. Donc, vous ne verrez pas l'en-tête Origin
usurpé par un navigateur. Un utilisateur malveillant pourrait créer une demande curl définissant manuellement l'en-tête Origin
, mais cette demande proviendrait de l'extérieur d'un navigateur et n'aurait peut-être pas d'informations spécifiques à ce dernier (telles que les cookies).
Rappelez-vous: la SCRO n’est pas une sécurité. Ne comptez pas sur CORS pour sécuriser votre site. Si vous fournissez des données protégées, utilisez des cookies ou des jetons OAuth ou autre chose que l'en-tête Origin
pour sécuriser ces données. Le Access-Control-Allow-Origin
en-tête dans CORS n'indique que les origines qui doivent être autorisées à faire des requêtes croisées. Ne comptez pas dessus pour rien de plus.
TLDR: Rien n'empêche un code malveillant d'usurper l'origine. Lorsque cela se produit, votre serveur ne le saura jamais et agira sur les requêtes. Parfois, ces demandes sont chères. Donc, n'utilisez pas CORS à la place de tout type de sécurité.
J'ai récemment joué avec la SCRO et je me suis posé la même question. Ce que j’ai découvert, c’est que le navigateur est peut-être assez intelligent pour connaître une demande CORS usurpé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-tête Origin
est un HTTP nom d'en-tête interdit qui ne peut pas être modifié par programme. Cela signifie que vous pouvez le modifier en 8 secondes environ à l'aide de Modifier les en-têtes pour Google Chrome .
Pour tester cela, j'ai configuré deux domaines client et un domaine de serveur. J'ai inclus une liste blanche CORS sur le serveur, qui autorisait les demandes CORS du client 1 mais pas du client 2. J'ai testé les deux clients, et les demandes CORS du client 1 ont abouti à l'échec du client 2.
Ensuite, j'ai usurpé l'en-tête Origin
du client 2 pour qu'il corresponde à celui du client 1. Le serveur a reçu l'en-tête spoofé Origin
et a réussi la vérification de la liste blanche (ou a échoué si vous êtes un type de gars à moitié vide). Après cela, le serveur a consenti consciencieusement en consommant toutes les ressources pour lesquelles il avait été conçu (appels à la base de données, envoi d’e-mails coûteux, envoi de messages SMS encore plus coûteux, etc.). Quand cela fut fait, le serveur envoya joyeusement le spoofé Access-Control-Allow-Origin
en-tête de nouveau au navigateur.
La documentation que j'ai lue indique que le Access-Control-Allow-Origin
La valeur reçue doit correspondre exactement à la valeur Origin
envoyée dans la requête. Ils correspondaient, alors j'ai été surpris de voir le message suivant dans Chrome:
XMLHttpRequest ne peut pas charger
http://server.dev/test
. L'en-tête 'Access-Control-Allow-Origin' a une valeurhttp://client1.dev
qui n'est pas égal à l'origine fournie. Originehttp://client2.dev
n'est donc pas autorisé à accéder.
La documentation que j'ai lue ne semble pas être exacte. L'onglet réseau de Chrome affiche clairement les en-têtes de requête et de réponse sous la forme http://client1.dev
, mais vous pouvez voir dans l’erreur que Chrome sait en quelque sorte que la véritable origine était http://client2.dev
et rejette correctement la réponse. Peu importe à ce stade car le serveur avait déjà accepté la demande d'usurpation d'identité et dépensé mon argent.
Juste une conclusion humble:
Q: La politique de la même origine (SOP) est-elle appliquée uniquement par les navigateurs?
A: Oui. Pour tous les appels que vous effectuez dans un navigateur, le navigateur applique définitivement le SOP). Le serveur peut ou non vérifier l'origine de la demande.
Q: Si une demande n'est pas conforme à la SOP, le navigateur la bloque-t-elle?
A: Non, cela dépasse l’autorité des navigateurs. Les navigateurs envoient simplement des requêtes croisées d’origine et attendent la réponse pour voir si l’appel est signalé par le serveur via Access-Control
- * en-têtes. Si le serveur ne renvoie pas Access-Control-Allow-Origin
en-tête, ne renvoie pas l’origine de l’appelant ou ne renvoie pas *
dans l'en-tête, tout ce que le navigateur peut faire est de s'abstenir de fournir la réponse à l'appelant.
Q: Cela signifie-t-il que je ne peux pas usurper Origin
?
A: Dans le navigateur et l’utilisation de scripts, vous ne pouvez pas remplacer Origin
car il contrôle le navigateur. Toutefois, si vous souhaitez vous pirater, vous pouvez modifier les appels sortants de VOTRE navigateur en utilisant des extensions de navigateur ou d'autres outils que vous installez sur votre ordinateur. Vous pouvez également émettre des appels HTTP
à l'aide de curl
, Python
, C#
, etc. et modifiez l'en-tête Origin
pour tromper le serveur.
Q: Donc, si je peux tromper le serveur en modifiant Origin
, cela signifie-t-il que CORS
n'est pas sécurisé?
A:CORS
ne dit rien sur la sécurité - c’est-à-dire l’authentification et l’autorisation des demandes. Il appartient aux serveurs d’inspecter les demandes et de les authentifier/autoriser par tout mécanisme avec lequel ils travaillent, tels que 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 connectez à votre site Web et qu'un code de script malveillant tente d'envoyer une demande au site Web de votre banque pour consulter votre solde. Le site Web de votre banque fait confiance aux informations d'identification provenant de votre site Web pour que la demande soit authentifiée et qu'une réponse HTTP
soit générée pour le code malveillant. Si le site Web de votre banque ne se soucie pas de partager ses points de terminaison avec d'autres origines, il ne comprend pas Access-Control-Allow-Origin
en-tête dans la réponse. Maintenant, à l’arrivée de la demande, le navigateur réalise qu’il s’agissait d’une demande de Cross Origins, mais la réponse ne montre pas que le serveur était disposé à partager la ressource (ici le point de terminaison de la requête solde) avec votre site Web. Donc, le flux est interrompu et le résultat renvoyé n'atteindra jamais le code malveillant.