37

我想知道为什么不能使用 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 应用程序也有效,如果我使用我的补丁。

4

8 回答 8

25

我相信你会通过工作草案并找到

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

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

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

最后,禁止覆盖 Headers 或为某些字段(如Content-LengthCookieethos 和secure design approach. 这是为了阻止或至少试图阻止 HTTP 请求走私

于 2013-03-07T08:57:37.793 回答
16

您可以禁用此行为:

var xhr = new XMLHttpRequest();
xhr.setDisableHeaderCheck(true);
xhr.open(...);
...
于 2013-03-07T09:19:59.423 回答
8

众所周知,对于浏览器,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

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

祝你好运!

于 2013-03-11T07:19:09.430 回答
4

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

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

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

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

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

于 2013-03-08T18:25:06.410 回答
2

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

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

于 2013-03-06T12:36:45.667 回答
1

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

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

我遇到了几个问题:

  1. Source Gist 已过时,对我不起作用。例如“请求”库 API 已更改。
  2. 我可能会使用 socket.io-client 的“xmlhttprequest”库,并且不会安装在与 socket.io-client 相同的级别上。
  3. 原始的“socket.io-client”(0.9.16)使用不支持“setDisableHeaderCheck”方法(但 1.6.0 支持)的“xmlhttprequest”(1.4.2)。所以,我做了一个叉子并使用它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”传输并像原始 gist 那样模拟 XMLHttpRequest。

于 2014-04-08T11:44:05.623 回答
0

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

于 2022-01-15T05:08:44.070 回答
-1

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

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

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

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

于 2019-09-30T18:48:55.413 回答