On dit qu'au lieu d'ajouter tous les domaines aux CORS , on ne devrait ajouter qu'un ensemble de domaines. Pourtant, il n'est parfois pas trivial d'ajouter un ensemble de domaines. Par exemple. si je souhaite exposer publiquement une API, pour chaque domaine qui souhaite appeler cette API, je devrai être contacté pour ajouter ce domaine à la liste des domaines autorisés.
J'aimerais prendre une décision de compromis consciente entre les implications de sécurité et moins de travail.
Les seuls problèmes de sécurité que je vois sont les attaques attaques DoS et CSRF . Les attaques CSRF peuvent déjà être réalisées avec des éléments IMG et des éléments FORM. Les attaques DoS liées à CORS peuvent être surmontées en bloquant les demandes sur l'en-tête du référent.
Suis-je absent des implications de sécurité?
=== Modifier ===
Access-Control-Allow-Credentials
L'en-tête n'est pas définiÀ l'exception de celle de csauve
, aucune des réponses ne répond à ma question d'origine.
Pour répondre à ma question; Il semble que tant que Access-Control-Allow-Credentials
n'est pas défini, il n'y a donc aucun problème de sécurité.
(Ce qui me fait me demander pourquoi la spécification nécessite un contrôle en amont lorsque Access-Control-Allow-Credentials
n'est pas défini?)
Les attaques de contrefaçon de demande intersite sont de loin la principale préoccupation que traite Access-Control-Allow-Origin.
Ryan a certainement raison concernant la récupération de contenu. Cependant, au sujet de la demande, il y a plus à dire ici. De nombreux sites Web fournissent désormais des services Web RESTful qui exposent un large éventail de fonctionnalités pouvant impliquer des modifications importantes dans le backend. Très souvent, ces services RESTful sont destinés à être invoqués avec une requête XHR (par exemple AJAX) (probablement avec un " Single Page Application " comme frontal). Si un utilisateur a une session active autorisant l'accès à ces services lorsqu'il visite un site tiers malveillant, ce site peut essayer d'appeler ces REST points de terminaison dans les coulisses, en transmettant des valeurs qui pourraient compromettre l'utilisateur ou le site . Selon la façon dont les services REST sont définis, il existe différentes manières de se protéger contre cela.
Dans le cas spécifique des services Web REST pour une application à page unique, vous pouvez dicter que toutes les demandes aux points de terminaison backend REST sont effectuées avec XHR et refuser toute demande non XHR. Vous pouvez dicter cela en vérifiant la présence d'un en-tête de demande personnalisé (quelque chose comme X-Requested-With de jQuery). Seules les demandes de type XHR peuvent définir ces en-têtes; les requêtes simples GET et POST des formulaires et des ressources incorporées ne le peuvent pas. Enfin, la raison pour laquelle nous voulons dicter les demandes XHR nous ramène à la question d'origine - les demandes XHR sont soumises aux règles CORS.
Si vous avez autorisé Access-Control-Allow-Origin: *
, N'importe quel site pourrait faire une demande AJAX au nom de l'utilisateur à vos points de terminaison REST. Si vos points de terminaison REST impliquent tout type de données sensibles ou permettent la persistance des données, il s'agit d'une vulnérabilité de sécurité inacceptable. Au lieu de cela, appliquez les demandes XHR uniquement comme je l'ai décrit et définissez une liste blanche des origines autorisées à effectuer ces demandes.
Il convient de souligner que si vos points de terminaison REST n'exposent aucune information sensible ou s'ils ne permettent pas à l'utilisateur de modifier les données de manière persistante, alors Access-Control-Allow-Origin: *
Peut être la décision appropriée. Google Maps, par exemple, fournit des vues en lecture seule dans les données cartographiques publiques; il n'y a aucune raison de restreindre les sites tiers qui pourraient souhaiter invoquer ces services.
Vieille question, mais beaucoup de mauvaises réponses ici, donc je dois ajouter la mienne.
Si vous ne définissez pas Access-Control-Allow-Credentials
, et vous effectuez une authentification sans cookie (c'est-à-dire que l'appelant fournit un en-tête d'autorisation de support), vous n'avez donc pas besoin de mettre les origines en liste blanche. Faites simplement écho à l'Origine dans Access-Control-Allow-Origin
.
Une API REST bien structurée peut être appelée en toute sécurité depuis n'importe quelle origine.
Vous pouvez en envoyer plusieurs, comme:
Access-Control-Allow-Origin: http://my.domain.com https://my.domain.com http://my.otherdomain.com
mais je le déconseille. Conservez plutôt une liste blanche de domaines autorisés. Disons:
allowed = [ "X", "Y", "A.Z" ];
Si vous recevez une demande de X
, vous répondez par:
Access-Control-Allow-Origin: X
Si vous recevez une demande de A.Z
vous répondez par:
Access-Control-Allow-Origin: A.Z
Si vous recevez une demande d'un domaine qui n'est pas autorisé, répondez par une erreur ou aucune politique CORS.
Toutes les demandes XHR enverront un en-tête Origin
, alors utilisez-le. Et vous n'avez qu'à envoyer les en-têtes de stratégie CORS pour la demande OPTIONS
, pas la GET/POST/HEAD
demande qui suit.
Le principal problème que je vois est que vous exposez tous vos domaines. Vous disposez peut-être d'un domaine d'administration sécurisé comme: https://admin.mydomain.com
, ou vous avez peut-être un site Web de produit qui n'est pas encore prêt à être lancé. Vous ne voulez pas inclure quoi que ce soit qui n'est pas absolument nécessaire pour la demande en cours.
Et *
est juste extrêmement paresseux.
CORS consiste à récupérer du contenu, pas seulement à faire la demande. Lorsque vous obtenez une ressource via une balise img ou script, vous pouvez inciter le navigateur de quelqu'un à faire une demande de style CSRF. C'est normal, et vous pouvez vous protéger contre cela avec un jeton CSRF normal.
Avec CORS activé sur tous les domaines, vous pouvez désormais demander à javascript sur un site attaquant de faire une demande et de récupérer le contenu, en envahissant leur vie privée.
Exemple:
Imaginez que votre dos active CORS pour tous les domaines. Maintenant, je fais un site Web qui fait une demande à yourimaginarybank.com/balance
Une demande IMG ne ferait rien, car mon javascript ne peut pas obtenir ce qui était dans le html de cette page sur le site Web de votre banque. Maintenant qu'ils ont activé CORS, le javascript de mon site récupère en fait une page HTML avec votre solde dessus et l'enregistre sur mon serveur. Non seulement je peux faire une demande GET comme avant, mais maintenant je peux voir ce qu'il y a à l'intérieur. Il s'agit d'un énorme problème de sécurité.
Comment résoudre le problème sans ajouter une grande liste dans vos en-têtes? Chaque demande CORS est effectuée avec l'en-tête Origin. La meilleure solution consiste probablement à lire l'en-tête Origin, puis à interroger une base de données pour voir si elle est sur la liste blanche, comme l'a suggéré Fritz dans sa réponse.