web-dev-qa-db-fra.com

Pourquoi les cookies et les en-têtes set-cookie ne peuvent pas être définis lors de la création de xmlhttprequest à l'aide de setRequestHeader?

Je me demandais pourquoi on ne peut pas définir les en-têtes de cookie en utilisant setRequestHeader. Y a-t-il une raison spécifique ou simplement qu'ils sont ajoutés par le navigateur lui-même, donc ces en-têtes sont désactivés? Y a-t-il un problème de sécurité?

- Modifier

Je travaille sur node.js et j'ai utilisé le module xmlhttprequest. Voici le code de test:

var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.withCredentials = true;
xhr.setRequestHeader('Cookie', "key=value");
xhr.send(null);

Ici, je dois définir cookie-header comme node.js' xmlhttprequest n'ajoute pas explicitement l'en-tête du cookie (comme le font les navigateurs). Lorsque vous essayez de le faire, xmlhttprequest donne l'erreur "Refused to set unsafe header ".

Bien que j'aie trouvé un correctif et réussi à envoyer l'en-tête du cookie. Mais vous vous demandez pourquoi il a été désactivé pour définir l'en-tête de cookie? Partout où j'ai lu, j'ai trouvé que c'était nécessaire pour l'intégrité des données et la sécurité, mais quelle sécurité peut être violée dans ce cas, n'est mentionnée nulle part. Je veux évaluer si ce problème d'intégrité des données est également valable pour l'application node.js si j'utilise mon correctif.

31
jsist

Je suis sûr que vous auriez parcouru le projet de travail et trouvé

Les en-têtes ci-dessus sont contrôlés par l'agent utilisateur pour lui permettre de contrôler ces aspects du transport.

Tout d'abord, nous devons comprendre, Ce sont des normes qui fonctionnent comme des lignes directrices pour l'interopérabilité des fonctions entre différents navigateurs. Ce n'est pas obligatoire pour le navigateur et les navigateurs ont donc un niveau d'adhésion différent à cette norme pour différentes raisons.

Deuxièmement, techniquement parlant, vous pouvez émuler un agent utilisateur, traiter votre programme comme un navigateur et définir très bien ces valeurs selon les normes mentionnées.

Enfin, l'intention de ne pas remplacer les en-têtes ou de configurer des en-têtes pour certains champs comme Content-Length, Cookie ethos le secure design approach. C'est pour décourager ou au moins essayer de décourager contrebande de requêtes HTTP .

23
Manish Singh

Vous pouvez désactiver ce comportement:

var xhr = new XMLHttpRequest();
xhr.setDisableHeaderCheck(true);
xhr.open(...);
...
14
robertklep

Comme il est bien connu, pour les navigateurs, les cookies (entre autres propriétés) doivent être soigneusement gérés pour empêcher des tiers de voler des sessions utilisateur (ou d'autres données). Il s'agit d'un problème avec les navigateurs et de la nature incontrôlée de la visite d'un site Web qui exécute du Javascript arbitraire.

Bien sûr, ce risque d'exécution de code arbitraire est soit faible soit sans risque pour node.js, car vous n'exécutez qu'un script que vous avez écrit qui peut exécuter un autre code que vous avez prévu.

Si vous regardez le code source de driverdan's XMLHttpRequest.js vous trouverez:

 // These headers are not user setable.   
 // The following are allowed but banned in the spec:   
 // * user-agent   
 var forbiddenRequestHeaders = [
    "accept-charset",
    "accept-encoding",
    "access-control-request-headers",
    "access-control-request-method",
    "connection",
    "content-length",
    "content-transfer-encoding",
    "cookie",
    "cookie2",
    "date",
    "expect",
    "Host",
    "keep-alive",
    "Origin",
    "referer",
    "te",
    "trailer",
    "transfer-encoding",
    "upgrade",
    "via"   ];

Cela répond à votre question spécifique de savoir pourquoi la restriction s'applique particulièrement à ce script utilisé pour node.js - le codeur suivait la spécification (aussi étroitement que possible), malgré le sentiment que ce n'était probablement pas une précaution de sécurité requise dans node.js. Néanmoins, ce niveau de sécurité par défaut est facilement modifié.

Comme l'a souligné robertklep, vous pouvez désactiver cette précaution par défaut en utilisant la méthode setDisableHeaderCheck. Et oui, ce dernier point répond ou contribue de manière significative à une réponse à votre question, car dans votre question, vous avez déclaré:

I have found a patch and successfully able to send the cookie-header

Nous avons maintenant découvert que vous n'aviez pas besoin de ce patch.

Bonne chance!

8
Todd

Oui, il est requis pour l'intégrité et la sécurité des données. Pour comprendre cela, vous devez comprendre le rôle des cookies dans les méthodes de demande HTTP.

Les cookies sont importants pour identifier l'utilisateur, le navigateur, la connexion, etc. et sont stockés sur le navigateur Web. JavaScript vous permet de manipuler les cookies, mais pas tous les cookies du navigateur. Voir cookies HTTP , ceux-ci ne sont définis que par le navigateur, afin que l'utilisateur ne puisse pas en abuser (via JavaScript).

Sur un navigateur pris en charge, un cookie de session HttpOnly sera utilisé uniquement lors de la transmission de requêtes HTTP (ou HTTPS), limitant ainsi l'accès à partir d'autres API non HTTP (telles que JavaScript).

Lorsque vous envoyez xmlhttprequest, il lit les cookies HttpOnly et les envoie au serveur via l'en-tête Cookie. Maintenant, si vous faites xhr.setRequestHeader('Cookie', "key=value");, vous essayez de falsifier les cookies envoyés au serveur. setRequestHeader ajoutera key=value qui peut compromettre l'intégrité des cookies envoyés.

Ceux-ci sont utilisés par le serveur pour authentifier l'utilisateur (session, compte de messagerie ou tout compte). Cela permet essentiellement au serveur d'empêcher l'utilisation abusive des cookies pour accéder au serveur.

4
user568109

la documentation mentionne que cela est fait pour protéger l'intégrité des données. http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method

Les en-têtes ci-dessus sont contrôlés par l'agent utilisateur pour lui permettre de contrôler ces aspects du transport. Cela garantit l'intégrité des données dans une certaine mesure. Les noms d'en-tête commençant par Sec- ne peuvent pas être définis pour permettre la création de nouveaux en-têtes garantissant qu'ils ne proviendront pas de XMLHttpRequest.

2

J'ai pu résoudre ce problème en utilisant le Gist suivant:
https://Gist.github.com/killmenot/9976859

L'idée originale est tirée d'ici:
https://Gist.github.com/jfromaniello/4087861

J'ai rencontré plusieurs problèmes:

  1. Source Gist est obsolète et ne fonctionne pas pour moi. Par exemple, l'API lib "request" a été modifiée.
  2. Je pourrais travailler avec la bibliothèque "xmlhttprequest" de socket.io-client et ne pas installer au même niveau avec socket.io-client.
  3. Le "socket.io-client" d'origine (0.9.16) utilise "xmlhttprequest" (1.4.2) qui ne prend pas en charge la méthode "setDisableHeaderCheck" (contrairement à 1.6.0). Donc, je fais une fourchette et je l'utilise https://github.com/intspirit/socket.io-client/tree/0.9.16+201404081204

socket.io-client (1.0.0-pre) utilise engine.io-client qui utilise la version correcte de xmlhttprequest. Je suppose que dans le futur, j'utiliserai la version 1.0.0 au lieu de ma fourchette, spécifiez le transport "xhr-polling" et moquez XMLHttpRequest comme le fait le Gist d'origine.

1