HttpOnly cookie 如何与 AJAX 请求配合使用?
如果在基于 cookie 的访问限制的站点上使用 AJAX,则 JavaScript 需要访问 cookie。 HttpOnly cookies 能在 AJAX 网站上工作吗?
编辑 Microsoft 创建了一种防止 XSS 攻击的方法,如果指定了 HttpOnly,则不允许 JavaScript 访问 cookie。 FireFox后来采用了这一点。 所以我的问题是:如果您在 StackOverflow 等网站上使用 AJAX,是否可以选择 Http-Only cookie?
编辑2:问题2。如果HttpOnly的目的是阻止JavaScript访问cookie,并且您仍然可以通过XmlHttpRequest对象通过JavaScript检索cookie,HttpOnly的意义是什么< /强>?
编辑3:以下是维基百科的引用:
当浏览器收到这样的 cookie 时,它应该在接下来的 HTTP 交换中照常使用它,但不会使其对客户端脚本可见。[32]
HttpOnly
标志不属于任何标准,并且并未在所有浏览器中实现。 请注意,当前无法阻止通过 XMLHTTPRequest 读取或写入会话 cookie。 [33]。
据我所知,当您使用 HttpOnly 时,document.cookie
会被阻止。 但似乎您仍然可以读取 XMLHttpRequest 对象中的 cookie 值,从而允许 XSS。 HttpOnly 如何让您更安全? 通过使cookie本质上只读?
在您的示例中,我无法写入您的 document.cookie
,但我仍然可以窃取您的 cookie 并使用 XMLHttpRequest 对象将其发布到我的域。
<script type="text/javascript">
var req = null;
try { req = new XMLHttpRequest(); } catch(e) {}
if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
req.open('GET', 'http://stackoverflow.com/', false);
req.send(null);
alert(req.getAllResponseHeaders());
</script>
编辑4:抱歉,我的意思是您可以将 XMLHttpRequest 发送到 StackOverflow 域,然后将 getAllResponseHeaders() 的结果保存到字符串中,用正则表达式输出 cookie,然后将其发布到外部领域。 看起来维基百科和 ha.ckers 都同意我的观点,但我很乐意接受再教育...
最终编辑:啊,显然两个网站都错了,这实际上是一个 FireFox 中的错误。 IE6和IE6 7 实际上是目前唯一完全支持 HttpOnly 的浏览器。
重申一下我所学到的一切:
- HttpOnly 限制 IE7 和 IE7 中对 document.cookie 的所有访问。 和 FireFox(不确定其他浏览器)
- HttpOnly 从 IE7 中的 XMLHttpObject.getAllResponseHeaders() 中的响应标头中删除 cookie 信息。
- XMLHttpObject 只能提交到它们源自的域,因此不存在 cookie 的跨域发布。
编辑:此信息可能不再是最新的。
JavaScript needs access to cookies if AJAX is used on a site with access restrictions based on cookies. Will HttpOnly cookies work on an AJAX site?
Edit: Microsoft created a way to prevent XSS attacks by disallowing JavaScript access to cookies if HttpOnly is specified. FireFox later adopted this. So my question is: If you are using AJAX on a site, like StackOverflow, are Http-Only cookies an option?
Edit 2: Question 2. If the purpose of HttpOnly is to prevent JavaScript access to cookies, and you can still retrieve the cookies via JavaScript through the XmlHttpRequest Object, what is the point of HttpOnly?
Edit 3: Here is a quote from Wikipedia:
When the browser receives such a cookie, it is supposed to use it as usual in the following HTTP exchanges, but not to make it visible to client-side scripts.[32] The
HttpOnly
flag is not part of any standard, and is not implemented in all browsers. Note that there is currently no prevention of reading or writing the session cookie via a XMLHTTPRequest. [33].
I understand that document.cookie
is blocked when you use HttpOnly. But it seems that you can still read cookie values in the XMLHttpRequest object, allowing for XSS. How does HttpOnly make you any safer than? By making cookies essentially read only?
In your example, I cannot write to your document.cookie
, but I can still steal your cookie and post it to my domain using the XMLHttpRequest object.
<script type="text/javascript">
var req = null;
try { req = new XMLHttpRequest(); } catch(e) {}
if (!req) try { req = new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
if (!req) try { req = new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
req.open('GET', 'http://stackoverflow.com/', false);
req.send(null);
alert(req.getAllResponseHeaders());
</script>
Edit 4: Sorry, I meant that you could send the XMLHttpRequest to the StackOverflow domain, and then save the result of getAllResponseHeaders() to a string, regex out the cookie, and then post that to an external domain. It appears that Wikipedia and ha.ckers concur with me on this one, but I would love be re-educated...
Final Edit: Ahh, apparently both sites are wrong, this is actually a bug in FireFox. IE6 & 7 are actually the only browsers that currently fully support HttpOnly.
To reiterate everything I've learned:
- HttpOnly restricts all access to document.cookie in IE7 & and FireFox (not sure about other browsers)
- HttpOnly removes cookie information from the response headers in XMLHttpObject.getAllResponseHeaders() in IE7.
- XMLHttpObjects may only be submitted to the domain they originated from, so there is no cross-domain posting of the cookies.
edit: This information is likely no longer up to date.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
澄清一下 - 从服务器的角度来看,AJAX 请求所请求的页面本质上与用户单击链接完成的标准 HTTP get 请求没有什么不同。 所有正常的请求属性:用户代理、ip、会话、cookies 等都会传递到服务器。
As clarification - from the server's perspective, the page that is requested by an AJAX request is essentially no different to a standard HTTP get request done by the user clicking on a link. All the normal request properties: user-agent, ip, session, cookies, etc. are passed to the server.
这还有一点。
Ajax 并不严格要求 cookie,但正如其他发帖者提到的那样,它们可能很有用。 将 cookie 标记为 HTTPOnly 以将其隐藏在脚本中只能部分起作用,因为并非所有浏览器都支持它,而且还因为有常见的解决方法。
奇怪的是 XMLHTTPresponse 标头提供了 cookie,从技术上讲,服务器不必随响应返回 cookie。 一旦在客户端上设置,它就会保持设置状态直到过期。 尽管有一些方案会根据每个请求更改 cookie,以防止重复使用。 因此,您可以通过更改服务器以不在 XMLHTTP 响应上提供 cookie 来避免这种解决方法。
但总的来说,我认为 HTTPOnly 应该谨慎使用。 存在跨站点脚本攻击,其中攻击者安排用户使用简单的发布表单(不使用 XMLHTTP)提交来自另一个站点的类似 ajax 的请求,并且浏览器的仍然活动的 cookie 将验证该请求。
如果您想确保 AJAX 请求经过身份验证,则请求本身和 HTTP 标头需要包含 cookie。 例如,通过使用脚本或独特的隐藏输入。 HTTPOnly 会阻碍这一点。
通常需要 HTTPOnly 的有趣原因是防止网页上包含的第三方内容窃取 cookie。 但有很多有趣的原因让我们对包含第三方内容持谨慎态度,并积极过滤它。
There's a bit more to this.
Ajax doesn't strictly require cookies, but they can be useful as other posters have mentioned. Marking a cookie HTTPOnly to hide it from scripts only partially works, because not all browsers support it, but also because there are common workarounds.
It's odd that the XMLHTTPresponse headers are giving the cookie, technically the server doesn't have to return the cookie with the response. Once it's set on the client, it stays set until it expires. Though there are schemes in which the cookie is changed with every request to prevent re-use. So you may be able to avoid that workaround by changing the server to not provide the cookie on the XMLHTTP responses.
In general though, I think HTTPOnly should be used with some caution. There are cross site scripting attacks where an attacker arranges for a user to submit an ajax-like request originating from another site, using simple post forms, without the use of XMLHTTP, and your browser's still-active cookie would authenticate the request.
If you want to be sure that an AJAX request is authenticated, the request itself AND the HTTP headers need to contain the cookie. Eg through the use of scripts or unique hidden inputs. HTTPOnly would hinder that.
Usually the interesting reason to want HTTPOnly is to prevent third-party content included on your webpage from stealing cookies. But there are many interesting reasons to be very cautious about including third-party content, and filter it aggressively.
不一定,这取决于你想做什么。 你能详细说明一下吗? AJAX 不需要访问 cookie 即可工作,它可以自行发出请求来提取信息,AJAX 调用发出的页面请求可以访问 cookie 数据和信息。 将其传递回调用脚本,无需 Javascript 直接访问 cookie
Not necessarily, it depends what you want to do. Could you elaborate a bit? AJAX doesn't need access to cookies to work, it can make requests on its own to extract information, the page request that the AJAX call makes could access the cookie data & pass that back to the calling script without Javascript having to directly access the cookies
当您进行 AJAX 调用时,浏览器会自动处理 Cookie,因此您的 Javascript 无需处理 Cookie。
Cookies are automatically handled by the browser when you make an AJAX call, so there's no need for your Javascript to mess around with cookies.
来自浏览器的所有 HTTP 请求都会传输相关站点的 cookie 信息。 JavaScript 既可以设置也可以读取cookie。 根据定义,Ajax 应用程序不需要 Cookie,但大多数 Web 应用程序都需要它们来维护用户状态。
对您的问题的正式回答是这样的:“如果使用 AJAX,JavaScript 是否需要访问 cookie?” - 因此是“不”。 例如,考虑使用 Ajax 请求来提供自动建议选项的增强搜索字段。 在这种情况下不需要 cookie 信息。
All HTTP requests from your browser transmit your cookie information for the site in question. JavaScript can both set and read cookies. Cookies are not by definition required for Ajax applications, but they are required for most web applications to maintain user state.
The formal answer to your question as phrased - "Does JavaScript need access to cookies if AJAX is used?" - is therefore "no". Think of enhanced search fields that use Ajax requests to provide auto-suggest options, for example. There is no need of cookie information in that case.
不,AJAX 调用请求的页面也可以访问 cookie 这就是检查您是否登录的方法。
您可以使用 Javascript 进行其他身份验证,但我不相信它,我总是更喜欢在后端进行任何类型的身份验证检查。
No, the page that the AJAX call requests has access to cookies too & that's what checks whether you're logged in.
You can do other authentication with the Javascript, but I wouldn't trust it, I always prefer putting any sort of authentication checking in the back-end.
是的,cookie 对于 Ajax 非常有用。
将身份验证放在请求 URL 中是不好的做法。 上周有一篇关于从 google 缓存获取 URL 中的身份验证令牌的新闻。
不,没有办法阻止攻击。 较旧的浏览器仍然允许通过 JavaScript 对 cookie 进行简单的访问。 你可以只绕过http,等等。只要有足够的努力,无论你想出什么,都可以绕过。 诀窍是让太多的努力变得不值得。
如果您想让您的网站更加安全(没有完美的安全性),您可以使用过期的身份验证 cookie。 那么,如果cookie被盗,攻击者必须在它过期之前使用它。 如果他们不这样做,那么您就有一个很好的迹象表明该帐户存在可疑活动。 时间窗口越短,安全性越好,但生成和维护密钥的服务器的负载就越大。
Yes, cookies are very useful for Ajax.
Putting the authentication in the request URL is bad practice. There was a news item last week about getting the authentication tokens in the URL's from the google cache.
No, there is no way to prevent attacks. Older browsers still allow trivial access to cookies via javascript. You can bypass http only, etc. Whatever you come up with can be gotten around given enough effort. The trick is to make it too much effort to be worthwhile.
If you want to make your site more secure (there is no perfect security) you could use an authentication cookie that expires. Then, if the cookie is stolen, the attacker must use it before it expires. If they don't then you have a good indication there's suspicious activity on that account. The shorter the time window the better for security but the more load it puts on your server generating and maintaining keys.
是的,仅 HTTP cookie 就适合此功能。 它们仍然会收到对服务器的 XmlHttpRequest 请求。
对于 Stack Overflow,cookie 会作为 XmlHttpRequest 请求的一部分自动提供。 我不知道 Stack Overflow 身份验证提供程序的实现细节,但 cookie 数据可能会自动用于在比“投票”控制器方法更低的级别验证您的身份。
更一般地说,AJAX 不需要 cookie。 XmlHttpRequest 支持(甚至是旧版浏览器上的 iframe 远程处理)就是技术上所需的全部。
但是,如果您想为支持 AJAX 的功能提供安全性,则适用与传统站点相同的规则。 您需要某种方法来识别每个请求背后的用户,而 cookie 几乎总是达到此目的的手段。
XmlHttpRequest 不会发出跨域请求(正是出于您所提到的各种原因)。
您通常可以注入脚本以使用 iframe 远程处理或 JSONP 将 cookie 发送到您的域,但 HTTP-Only 会再次保护 cookie,因为它无法访问。
除非您在服务器端破坏了 StackOverflow.com,否则您将无法窃取我的 cookie。
考虑这种情况:
使用 HTTP-Only cookie,第二步将是不可能的,从而挫败了我的 XSS 尝试。
这是正确的。 您仍然可以通过这种方式劫持会话。 不过,它确实大大减少了能够成功执行针对您的 XSS 攻击的人群。
但是,如果您回到我的示例场景,您可以看到 HTTP-Only 成功地切断了依赖于修改客户端 cookie 的 XSS 攻击(并不罕见)。
归根结底,a) 没有任何一项改进可以解决所有漏洞,b) 没有任何系统永远是完全安全的。 HTTP-Only是抵御 XSS 的有用工具。
同样,即使 XmlHttpRequest 的跨域限制不能 100% 成功地阻止所有 XSS 攻击,您仍然不会梦想消除该限制。
Yes, HTTP-Only cookies would be fine for this functionality. They will still be provided with the XmlHttpRequest's request to the server.
In the case of Stack Overflow, the cookies are automatically provided as part of the XmlHttpRequest request. I don't know the implementation details of the Stack Overflow authentication provider, but that cookie data is probably automatically used to verify your identity at a lower level than the "vote" controller method.
More generally, cookies are not required for AJAX. XmlHttpRequest support (or even iframe remoting, on older browsers) is all that is technically required.
However, if you want to provide security for AJAX enabled functionality, then the same rules apply as with traditional sites. You need some method for identifying the user behind each request, and cookies are almost always the means to that end.
XmlHttpRequest won't make cross-domain requests (for exactly the sorts of reasons you're touching on).
You could normally inject script to send the cookie to your domain using iframe remoting or JSONP, but then HTTP-Only protects the cookie again since it's inaccessible.
Unless you had compromised StackOverflow.com on the server side, you wouldn't be able to steal my cookie.
Consider this scenario:
With HTTP-Only cookies, the second step would be impossible, thereby defeating my XSS attempt.
That's correct. You can still session hijack that way. It does significantly thin the herd of people who can successfully execute even that XSS hack against you though.
However, if you go back to my example scenario, you can see where HTTP-Only does successfully cut off the XSS attacks which rely on modifying the client's cookies (not uncommon).
It boils down to the fact that a) no single improvement will solve all vulnerabilities and b) no system will ever be completely secure. HTTP-Only is a useful tool in shoring up against XSS.
Similarly, even though the cross domain restriction on XmlHttpRequest isn't 100% successful in preventing all XSS exploits, you'd still never dream of removing the restriction.
是的,它们对于基于 Ajax 的网站来说是一个可行的选择。 身份验证 cookie 不能由脚本操作,而只是由浏览器包含在向服务器发出的所有 HTTP 请求中。
脚本不需要担心会话 cookie 的内容 - 只要您通过了身份验证,那么由用户或脚本发起的对服务器的任何请求都将包含适当的 cookie。 脚本本身无法知道 cookie 的内容这一事实并不重要。
对于用于身份验证以外目的的任何 cookie,如果您希望脚本能够修改或读取这些 cookie,则可以在不使用 HTTP only 标志的情况下设置这些 cookie。 您可以选择哪些 cookie 应该仅是 HTTP,因此例如任何不敏感的内容,例如 UI 首选项(排序顺序、折叠左侧窗格或不折叠)都可以在 cookie 中与脚本共享。
我真的很喜欢仅 HTTP 的 cookie - 这是专有的浏览器扩展之一,真是一个绝妙的主意。
Yes, they are a viable option for an Ajax based site. Authentication cookies aren't for manipulation by scripts, but are simply included by the browser on all HTTP requests made to the server.
Scripts don't need to worry about what the session cookie says - as long as you are authenticated, then any requests to the server initiated by either a user or the script will include the appropriate cookies. The fact that the scripts cannot themselves know the content of the cookies doesn't matter.
For any cookies that are used for purposes other than authentication, these can be set without the HTTP only flag, if you want script to be able to modify or read these. You can pick and choose which cookies should be HTTP only, so for example anything non-sensitive like UI preferences (sort order, collapse left hand pane or not) can be shared in cookies with the scripts.
I really like the HTTP only cookies - it's one of those proprietary browser extensions that was a really neat idea.