HttpOnly cookie如何与AJAX请求一起使用?


195

如果在基于cookie的访问限制的网站上使用AJAX,则JavaScript需要访问cookie。HttpOnly cookie可以在AJAX网站上使用吗?

编辑: Microsoft创建了一种方法,通过在指定HttpOnly的情况下禁止对cookie的JavaScript访问来防止XSS攻击。FireFox后来采用了此方法。所以我的问题是:如果您在像StackOverflow这样的网站上使用AJAX,是否可以选择仅使用Http的cookie?

编辑2:问题2。如果HttpOnly的目的是防止JavaScript访问cookie,并且您仍然可以通过XmlHttpRequest对象通过JavaScript检索cookie,那么HttpOnly的意义何在?

编辑3:以下是维基百科的引文:

当浏览器收到这样的cookie时,应该在以下HTTP交换中照常使用它,而不是使其对客户端脚本可见。[32] 该HttpOnly标志不是任何标准的一部分,并且并非在所有浏览器中都实现。请注意,当前无法阻止通过XMLHTTPRequest读取或写入会话cookie。[33]。

我了解document.cookie您使用HttpOnly时会被阻止。但是似乎您仍然可以在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进行正则表达式,然后将其发布到外部域。看来Wikipedia和ha.ckers在这一点上与我达成了一致,但我很乐意接受再教育...

最终编辑:啊,显然两个站点都错了,这实际上是FireFox中错误。IE6和7实际上是当前唯一完全支持HttpOnly的浏览器。

重申我所学到的一切:

  • HttpOnly限制了对IE7和FireFox中document.cookie的所有访问(不确定其他浏览器)
  • HttpOnly从IE7的XMLHttpObject.getAllResponseHeaders()中的响应标头中删除cookie信息。
  • XMLHttpObjects只能提交到其起源的域,因此不存在cookie的跨域发布。

编辑:此信息可能不再是最新的。


我将您的示例放入了一个研究人员的脚本中,看起来FF不再显示cookie。优秀的研究和榜样。

也许使用同源策略,您无法向与脚本运行所在的域不同的域发出http请求;但是,我相信您可以通过使用window.location将用户重定向到页面并通过查询字符串参数传递所有信息来轻松传递cookie。
卡·马兹

@LucaMarzi“ 您无法向与脚本运行所在的域不同的域发出http请求您是在说站点X不能包含来自主机Y的图像吗?(自Mosaic以来所有浏览器都支持该功能吗?)
curiousguy

Answers:


64

是的,仅HTTP cookie可以使用此功能。它们仍将随XmlHttpRequest的请求一起提供给服务器。

对于Stack Overflow,cookie会作为XmlHttpRequest请求的一部分自动提供。我不知道Stack Overflow身份验证提供程序的实现细节,但是cookie数据可能会自动用于比“表决”控制器方法更低的级别来验证您的身份。

更一般地,是饼干不是必需的AJAX。技术上只需要XmlHttpRequest支持(或者在较旧的浏览器上甚至是iframe远程)。

但是,如果要为启用AJAX的功能提供安全性,则适用与传统站点相同的规则。您需要某种方法来识别每个请求背后的用户,而cookie几乎始终是达到此目的的手段。

在您的示例中,我无法写入您的document.cookie,但仍可以窃取您的cookie并使用XMLHttpRequest对象将其发布到我的域中。

XmlHttpRequest不会发出跨域请求(正是出于您所涉及的种种原因)。

通常,您可以使用iframe远程处理或JSONP注入脚本以将cookie发送到您的域,但是由于HTTP-Only无法访问,因此仅HTTP再次保护了cookie。

除非您在服务器端破坏了StackOverflow.com,否则您将无法窃取我的cookie。

编辑2:问题2。如果仅Http的目的是防止JavaScript访问cookie,并且您仍然可以通过XmlHttpRequest对象通过JavaScript检索cookie,那么Http的意义何在?

考虑这种情况:

  • 我找到了一种将JavaScript代码注入页面的途径。
  • Jeff加载了页面,而我的恶意JavaScript修改了他的cookie以匹配我的。
  • 杰夫为您的问题提供了出色的答案。
  • 因为他是使用我的Cookie数据而不是他的cookie数据提交的,所以答案将是我的。
  • 您投票赞成“我的”杰出回答。
  • 我的真实帐户很重要。

使用仅HTTP的cookie,第二步将是不可能的,从而挫败了我的XSS尝试。

编辑4:对不起,我的意思是您可以将XMLHttpRequest发送到StackOverflow域,然后将getAllResponseHeaders()的结果保存到字符串中,对cookie进行正则表达式,然后将其发布到外部域。看来Wikipedia和ha.ckers在这一点上与我达成了一致,但我很乐意接受再教育...

没错 您仍然可以通过这种方式进行会话劫持。尽管确实可以成功执行XSS骇客攻击,但确实可以使很多人成功。

但是,如果返回到我的示例场景,则可以看到仅HTTP 确实在哪些地方成功切断了依赖于修改客户端Cookie的XSS攻击(这并不罕见)。

可以归结为以下事实:a)没有任何一项改进可以解决所有漏洞,并且b)任何系统都不会完全安全。仅HTTP 支持XSS的有用工具。

同样,即使X​​mlHttpRequest上的跨域限制在阻止所有XSS漏洞方面并非100%成功,但您仍然永远不会梦想消除该限制。


许多框架将csrf 令牌放入cookie中。我想csrf除非您将csrf令牌放在隐藏的HTML元素中以供JS检索,否则需要检查的AJAX调用将无法进行。
用户

4

不一定,这取决于您要做什么。您能详细说明一下吗?AJAX不需要访问cookie即可工作,它可以自行发出请求以提取信息,AJAX调用发出的页面请求可以访问cookie数据并将其传递回调用脚本,而Javascript无需直接访问饼干


4

是的,对于基于Ajax的网站,它们是可行的选择。身份验证cookie不能通过脚本进行操作,而是仅由浏览器包含在对服务器发出的所有HTTP请求中。

脚本不必担心会话cookie的内容-只要您通过身份验证,那么由用户或脚本发起的对服务器的任何请求都将包含适当的cookie。脚本本身不能知道cookie的内容这一事实并不重要。

对于用于身份验证以外的任何cookie,如果您希望脚本能够修改或读取它们,则可以在不使用HTTP only标志的情况下设置它们。您可以选择哪些cookie仅应为HTTP,例如,可以使用脚本在cookie中共享任何不敏感的东西,例如UI首选项(排序顺序,是否折叠左窗格)。

我真的很喜欢仅使用HTTP的cookie,它是那些专有的浏览器扩展之一,真是一个不错的主意。


3

还有更多的东西。

Ajax并不严格要求cookie,但正如其他张贴者所提到的那样,它们可能很有用。将Cookie标记为HTTPOnly只能部分隐藏脚本,因为不是所有的浏览器都支持它,而且还存在一些常见的解决方法。

奇怪的是XMLHTTPresponse标头提供了cookie,从技术上讲,服务器不必返回带有响应的cookie。在客户端上进行设置后,它将保持设置状态,直到过期。尽管有些方案会在每次请求中更改cookie,以防止重复使用。因此,您可以通过将服务器更改为不在XMLHTTP响应上提供cookie来避免该解决方法。

但总的来说,我认为应谨慎使用HTTPOnly。在跨站点脚本攻击中,攻击者安排用户使用简单的发布表单,而不使用XMLHTTP,来提交来自另一个站点的类似ajax的请求,并且浏览器的活动cookie将对请求进行身份验证。

如果要确保对AJAX请求进行了身份验证,则请求本身和HTTP标头需要包含cookie。例如,通过使用脚本或唯一的隐藏输入。HTTPOnly会阻止这一点。

通常,希望使用HTTPOnly的有趣原因是防止网页上包含的第三方内容窃取cookie。但是,有很多有趣的原因对包含第三方内容并进行积极过滤非常谨慎。


1

当您进行AJAX调用时,浏览器会自动处理Cookie,因此您的Javascript无需摆弄Cookie。


1

因此,我假设JavaScript需要访问您的cookie。

来自浏览器的所有HTTP请求都会传输您所涉及站点的Cookie信息。JavaScript可以设置和读取cookie。根据定义,Cookie不是Ajax应用程序所必需的,但大多数Web应用程序都需要cookie来维护用户状态。

短语的正式答案-“如果使用AJAX,JavaScript是否需要访问cookie?” -因此为“否”。例如,考虑使用Ajax请求提供自动建议选项的增强搜索字段。在这种情况下,不需要Cookie信息。


XmlHttpRequest需要cookie。您提到的增强型搜索可能在登录页面后面。但是Javascript是否需要能够向VM公开cookie值是另一个问题。
Shiny和New安宇先生,2009年

1

需要说明的是-从服务器的角度来看,AJAX请求所请求的页面与用户单击链接完成的标准HTTP get请求本质上没有什么不同。所有正常的请求属性:用户代理,IP,会话,Cookie等均传递到服务器。


“会话”不是HTTP概念。这是框架在HTTP概念之上构建的高级概念。
curiousguy

0

不,AJAX呼叫请求的页面也可以访问Cookie,这就是检查您是否已登录的原因。

您可以使用Javascript进行其他身份验证,但我不信任它,我总是更喜欢在后端放置任何形式的身份验证检查。


0

是的,cookie对Ajax非常有用。

将身份验证放在请求URL中是不好的做法。上周有个新闻报道,关于从Google缓存中获取URL中的身份验证令牌。

不,没有办法防止攻击。较旧的浏览器仍然允许通过javascript轻松访问cookie。您只能绕过http等。只要有足够的努力,您想出的任何东西都可以解决。诀窍是要付出太多努力才值得。

如果您想使站点更加安全(没有完美的安全性),则可以使用过期的身份验证cookie。然后,如果cookie被盗,攻击者必须在cookie过期之前使用它。如果他们没有,那么您有充分的迹象表明该帐户存在可疑活动。时间窗口越短,安全性就越好,但是它会给服务器生成和维护密钥带来更多的负担。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.