3 votes

En-têtes Origin et Host pour les requêtes du même domaine

Nous avons des points de terminaison RESTful JSON servant des requêtes AJAX, avec la volonté de supporter le partage des ressources entre origines. Nous verrouillons les choses pour nous assurer que nous n'avons pas à nous soucier des attaques CSRF (Cross Site Request Forgery). Une partie de l'approche que nous utilisons consiste à vérifier la présence d'un en-tête d'origine et à s'assurer qu'il est inclus dans une liste blanche d'origines approuvées. Cependant, nous avons remarqué que certains navigateurs (dont Chrome et Safari) incluent l'en-tête Origin dans les requêtes AJAX POST, même si elles proviennent du même domaine (il ne s'agit donc pas d'une requête CORS).

Comme nous préférons ne pas obliger nos utilisateurs à mettre sur liste blanche le même domaine que celui à partir duquel les points d'extrémité REST sont servis, nous aimerions déterminer automatiquement si une requête donnée est ou non "Same Domain" ou "Cross Origin". Pour ce faire, notre meilleure tentative consiste actuellement à surveiller la présence d'un en-tête Origin et, s'il existe, à le comparer à la valeur de l'en-tête Host. Notre logique est la suivante : si l'origine correspond à l'hôte, la demande doit être "Same Domain" et nous n'avons donc pas besoin de vérifier l'origine dans la liste blanche.

Voici un extrait du code JS côté serveur que nous envisageons d'utiliser pour y parvenir :

     if (typeof (headers["Origin"]) !== "undefined" &&
         headers["Origin"].replace(new RegExp("^.*?//"), "") !== headers["Host"] &&
         !contains(allowedOrigins, headers.Origin) ) {
         return false;
     } else {
         return true;
     }

La comparaison des regexp est nécessaire car l'en-tête d'Origin ressemblera à ceci :

http://localhost:8080

Alors que l'en-tête Host ressemblera à ceci :

localhost:8080

J'utilise donc cette regexp pour enlever le premier http://.

Le problème est que nous n'avons vu aucune autre implémentation utilisant ou discutant cette approche. Cela nous fait penser qu'il ne s'agit peut-être pas d'une méthode appropriée, pour une raison quelconque. Donc, la question est - La comparaison de l'en-tête Host avec l'en-tête Origin est-elle un moyen sûr de déterminer si une requête provient du même domaine ? ?

Par ailleurs, le fait d'enlever le début de protocole:// de l'origine comme je l'ai montré va-t-il toujours donner la bonne valeur par rapport à l'hôte ?

3voto

johnwilander Points 476

Je vous conseille de vérifier plutôt l'en-tête Ajax : X-Requested-With : XMLHttpRequest

Same-origin Ajax peut ajouter des en-têtes personnalisés et presque tous les frameworks populaires tels que jQuery ajoutent X-Requested-With : XMLHttpRequest.

Pour CORS cependant, les en-têtes personnalisés provoquent une demande HTTP OPTIONS avant le vol.

Ainsi, si vous voyez X-Requested-With : XMLHttpRequest (ou tout autre en-tête personnalisé) sans pré-vol, vous savez qu'il s'agit d'un appel Ajax de même origine.

0voto

shashankaholic Points 1989

Votre approche actuelle consistant à comparer l'en-tête Host avec l'en-tête Origin pour déterminer la même origine échouera si si vous voulez passer à HTTPS plus tard. ou nous pouvons dire en cas de demande de protocole croisé .

Comme si votre code allait traiter ces deux origines de la même manière.

Origin : http://www.example.com Origin : https://example.com

Une autre approche sera utilisée Référent HTTP en-tête . Mais je ne préférerai pas l'utiliser parce que l'usurpation d'identité n'est pas une tâche impossible.

Je dirais qu'il vaut mieux prévenir que guérir. L'ajout d'un élément supplémentaire dans la liste des origines autorisées ne vous fera pas souffrir autant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X