繁体   English   中英

为什么在使用 setRequestHeader 制作 xmlhttprequest 时无法设置 cookie 和 set-cookie 标头?

[英]Why cookies and set-cookie headers can't be set while making xmlhttprequest using setRequestHeader?

我想知道为什么不能使用 setRequestHeader 设置cookie标头。 是否有任何特定原因,或者仅仅是浏览器本身添加了它们,所以这些标头被禁用了? 有什么安全问题吗?

- 编辑

我正在研究 node.js 并使用了xmlhttprequest模块。 以下是测试代码:

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

在这里,我需要将 cookie-header 设置为node.js' xmlhttprequest不要显式添加 cookie-header(就像浏览器一样)。 尝试这样做时, xmlhttprequest给出错误“ Refused to set unsafe header ”。

虽然我找到了一个补丁并成功发送了 cookie-header。 但是想知道为什么禁用设置 cookie-header ? 无论我在哪里阅读,都发现它是数据完整性和安全性所必需的,但是在这种情况下可以破坏哪些安全性,却没有提到任何地方。 我想评估这个数据完整性问题是否对 node.js 应用程序也有效,如果我使用我的补丁。

我相信你会完成工作草案并找到

上述标题由用户代理控制,以便控制传输的这些方面。

首先,我们需要了解,这些是作为不同浏览器之间功能互操作性指南的标准。 它不是针对浏览器的强制要求,因此浏览器由于不同的原因确实对该标准有不同程度的遵守。

其次,从技术上讲,您可以模拟用户代理,将您的程序视为浏览器,并且可以按照上述标准很好地设置这些值。

最后,意图是禁止覆盖Headers或为某些字段设置标题,例如Content-LengthCookie ethos这种secure design approach 这是为了阻止或至少试图阻止HTTP请求走私

您可以禁用此行为:

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

众所周知,对于浏览器,需要谨慎管理cookie(以及其他属性)以防止第三方窃取用户会话(或其他数据)。 这是浏览器的问题,以及访问运行任意Javascript的网站的不受控制的性质。

当然,任意代码执行的风险对于node.js来说是低风险或无风险,因为您只运行您编写的脚本,该脚本可能运行您计划的其他代码。

如果你看一下driverdan的XMLHttpRequest.js的源代码,你会发现:

 // 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"   ];

这回答了你为什么限制特别适用于node.js这个脚本的特定问题 - 编码器遵循规范(尽可能接近),尽管感觉它可能不是node.js中必需的安全预防措施。 然而,这个默认安全级别很容易修改。

正如robertklep指出的那样,您可以使用setDisableHeaderCheck方法禁用此默认预防措施。 是的,这个最后一点确实对你的问题的答案做出了回答或做出了重大贡献,因为在你提出的问题中你说:

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

我们现在发现你不需要那个补丁。

祝好运!

是的,它是数据完整性和安全性所必需的。 要理解这一点,您必须了解cookie在HTTP请求方法中的作用。

Cookie在识别用户,浏览器,连接等方面很重要,并存储在Web浏览器中。 JavaScript允许您操作cookie,但不能操纵浏览器上的所有cookie。 请参阅HTTP cookie ,这些仅由浏览器设置,因此用户不能滥用它(通过JavaScript)。

在支持的浏览器上,仅在传输HTTP(或HTTPS)请求时才使用HttpOnly会话cookie,从而限制来自其他非HTTP API(例如JavaScript)的访问。

当您发送xmlhttprequest时,它会读取HttpOnly cookie并通过Cookie标头发送到服务器。 现在,如果你做xhr.setRequestHeader('Cookie', "key=value"); ,你试图篡改发送到服务器的cookie。 setRequestHeader将添加额外的key=value ,这可能会影响发送的cookie的完整性。

服务器使用这些来验证用户(会话,电子邮件帐户或任何帐户)。 这实质上允许服务器防止滥用cookie来访问服务器。

文档提到这样做是为了保护数据完整性。 http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method

上述标题由用户代理控制,以便控制传输的这些方面。 这在一定程度上保证了数据完整性。 不允许将以Sec-开头的头名称设置为允许新的头文件被保证不会来自XMLHttpRequest。

我能够使用以下Gist解决此问题:
https://gist.github.com/killmenot/9976859

最初的想法来自这里:
https://gist.github.com/jfromaniello/4087861

我遇到了几个问题:

  1. Source Gist已过时,对我不起作用。 例如,“request”lib API已更改。
  2. 我可能使用socket.io-client的“xmlhttprequest”库,而不是与socket.io-client安装在同一级别。
  3. 原始的“socket.io-client”(0.9.16)使用不支持“setDisableHeaderCheck”方法的“xmlhttprequest”(1.4.2)(但1.6.0确实如此)。 所以,我做一个分叉并使用它https://github.com/intspirit/socket.io-client/tree/0.9.16+20140408120400

socket.io-client(1.0.0-pre)使用使用正确版本的xmlhttprequest的engine.io-client。 我想将来我将使用1.0.0版本而不是我的fork,指定“xhr-polling”传输并模拟XMLHttpRequest作为原始要点。

xhr.setRequestHeader('Cookie', "key=value");之前添加xhr._restrictedHeaders.cookie = false 但这是不好的方式,我不推荐使用它。

我认为这个答案不够完整。

正如所有的asnwers所说,你不能使用xhr.setRequestHeader('Cookie', "key=value"); 由于安全完整性而发送任何数据(浏览器无法判断您添加的值是否是真正的 cookie)。

使用此特殊标头的预期方法是让客户端浏览器自动获取与您请求的站点相关的所有 cookie 并将它们放在“Cookie”标头上,如果您的 cookie,您无需执行任何其他操作存在于您的浏览器中,它们将被发送。

...如果您想知道,存储在浏览器中的所有 cookie 都应该在每次来自您请求的服务器的响应向您发送回Set-Cookie标头时存储/更新。 因此,在请求中添加“Set-Cookie”标头是没有意义的,因为它是仅为响应保留的标头,并且不需要在您的请求中添加“Cookie”标头,因为您的浏览器已经这样做了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM