[英]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 应用程序也有效,如果我使用我的补丁。
您可以禁用此行为:
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
我遇到了几个问题:
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.