不安全Web源上的Secure Cookie存在性检测技术解析

本文深入探讨了一种XSLeak技术,允许攻击者从不安全的Web源检测Secure Cookie的存在性,分析了Strict Secure Cookies机制的机密性缺陷,并提供了PoC验证和防御方案。

不安全Web源上的Secure Cookie存在性检测技术

TL;DR

本文介绍了一种XSLeak技术,允许活跃网络攻击者从不安全的Web源观察某些Secure Cookie的存在与否,这些Cookie可能由该源的HTTPS对应方设置。

Cookie的脆弱起源

Netscape(更准确地说,是Lou Montulli)在1994年发明了Cookie,旨在为无状态的超文本传输协议(HTTP)引入持久客户端状态。当时,Web比现在静态得多。但随着浏览器脚本能力的出现,必须构建新的规则(统称为同源策略(SOP))以保护Web源彼此隔离。

Fabian Fäßler(又名LiveOverflow)最近发布了一个关于SOP的视频回顾,非常值得一看。

然而,由于Cookie早于SOP并已广泛使用,它们从未遵循SOP的规则。更具体地说,Cookie尚未(?)与源绑定:Cookie jar通过(名称、域、路径)三元组对Cookie进行键控,但Web源是(方案、主机、端口)三元组。IETF HTTP工作组一直在努力逐步改进Cookie的安全模型并弥合与SOP的差距,同时谨慎地最小化对现有Web应用程序的破坏。

严格安全Cookie

其中一个渐进式更改,被Chromium团队昵称为“严格安全Cookie”,解决了与标记为Secure的Cookie完整性相关的一些问题。Secure Cookie属性自诞生以来,阻止了不安全的Web源(例如方案为http的源)访问设置了该属性的Cookie。然而,曾有一段时间,不安全源仍然可以创建、删除或间接驱逐Secure Cookie;浏览器会将不安全上下文创建的Cookie发送到安全源,而安全源无法确定这些Cookie是在安全还是不安全的上下文中创建的。因此,来自活跃网络攻击者的会话固定等攻击仍然是一个问题。严格安全Cookie提案(Mike West,2015年)通过禁止不安全源执行以下操作来补救情况:

  • 创建标记为Secure的Cookie,以及
  • 用非Secure Cookie覆盖(即屏蔽或遮蔽)现有的Secure Cookie。

第二个限制(我称之为覆盖限制)在本文其余部分讨论的XSLeak技术中至关重要。由于其机制有点技术性,我在此包含RFC 6265 bis(版本01)存储算法的相关步骤以供完整:

如果Cookie的secure-only-flag未设置,且request-uri的方案组件不表示“安全”协议,则中止这些步骤并完全忽略Cookie,如果Cookie存储包含一个或多个满足以下所有条件的Cookie:

  • 它们的名称与新创建的Cookie的名称匹配。
  • 它们的secure-only-flag为true。
  • 它们的域域匹配新创建Cookie的域,反之亦然。
  • 新创建Cookie的路径路径匹配现有Cookie的路径。

如今,所有现代浏览器都支持此行为;这一变化无疑是受欢迎的,因为它解决了Cookie的一些完整性问题。然而,在通读整个与Cookie相关的RFC系列时,我意识到严格安全Cookie的覆盖限制为了完整性牺牲了一些机密性。

Secure Cookie的存在性检测

考虑一个Cookie:

  • 名为foo
  • 域字段为example.com
  • 路径字段为/
  • 标记为Secure

覆盖限制确实允许不安全源http://example.com确定此类Cookie是否存在于浏览器的Cookie jar中。如何实现?不安全源可以尝试设置此类Cookie(尽管没有Secure属性),然后立即测试它是否存在于document.cookie返回的Cookie字符串中。因此,活跃网络攻击者尽管无法解密受害者的流量,但可能能够观察受害者浏览器中Secure Cookie的存在。当我在Twitter上向Mike West本人询问此事时,他确认覆盖限制存在机密性问题,但暗示我们不应期望很快有适当的修复:

这里确实存在信息泄漏。理想情况下,我们将通过将世界分为安全和非安全源来修复它,可能通过类似https://github.com/sbingler/Origin-Bound-Cookies或https://github.com/mikewest/scheming-cookies的东西。

在目标网站易受跨站脚本攻击的条件下,类似技术实际上可用于检测HttpOnly Cookie的存在,因为浏览器忽略通过“非HTTP”API(例如document.cookie)更新HttpOnly Cookie的尝试。更多细节,请参阅RFC 6265 bis(版本10)第5.5节中的步骤22。

概念验证

概念验证胜过千言万语。对于此示例,我将使用实际的https://example.com网站和一个名为“foo”的Cookie。为了模拟活跃网络攻击者,我将使用Burp Suite Community的拦截Web代理。

  1. 启动Burp和关联的代理浏览器。
  2. 在Burp的Proxy选项卡上,确保拦截功能已关闭。
  3. 访问安全源https://example.com。
  4. 可选:打开浏览器的控制台并运行以下JavaScript代码:document.cookie='foo=; Secure';
  5. 现在您的浏览器中应该有一个三元组为(foo, example.com, /)且标记为Secure的Cookie。
  6. 在Burp的Proxy选项卡上,打开拦截功能。
  7. 访问不安全源http://example.com。
  8. 在Burp的Proxy选项卡上,右键单击步骤6产生的请求,并选择“Do intercept » Response to this request”。
  9. 原样转发请求。
  10. 作为活跃网络攻击者,将该请求的整个响应替换为以下内容:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Set-Cookie: foo=
Connection: close
Content-Length: 156

<script>
  const found = /(^|; )foo=/.test(document.cookie);
  if (found) {
    document.cookie="foo=; Max-Age=-1";
  }
  alert(!found);
</script>
  1. 转发步骤9中伪造的响应。

将弹出一个警报模态框,指示以下陈述的真值:

受害者浏览器中存在名为foo的Secure Cookie。

如果您在可选的第四步创建了名为“foo”的Secure Cookie,则由于覆盖限制,创建名为“foo”的非Secure Cookie(见第3行)失败。因此,在为不安全源生成的Cookie字符串中找不到名为“foo”的Cookie,警报模态框显示“true”。

现在清除名为“foo”的Secure Cookie并重复所有步骤(除了步骤4)。这次,没有Secure对应项的阻碍,可以创建名为“foo”的非Secure Cookie。因此,它存在于为不安全源生成的Cookie字符串中,立即过期(见第10行)以实现最大隐蔽性,警报模态框显示“false”。

编辑: 实际上,正如@Haxatron在Twitter上提醒我的那样,严格安全Cookie并未真正解决Secure Cookie的所有完整性问题;更具体地说,覆盖限制不阻止不安全源在创建特定Cookie(尽管没有Secure属性)的竞争中击败其安全对应项,如此PoC所示。不过,Cookie名称前缀确实有助于解决此问题;有关此主题的更多信息,请参阅此Security Stack Exchange问答。

影响

活跃网络攻击者(如 shady咖啡店所有者甚至道德有问题的ISP)可能能够将此技术武器化用于登录检测。通过针对依赖Secure Cookie识别会话的网站,攻击者确实可能能够确定受害者是否登录到该网站。受害者可能只愿意通过HTTPS与目标交互;攻击者只需要伪造受害者对任何不安全源的第一个请求的响应,并在伪造响应(如我的PoC步骤7所述)之前将它们重定向到目标不安全源。在大局中——双关语无意——此技术可能被恶意行为者滥用,以根据人们登录的网站(新闻媒体、约会网站等)对他们进行分析。

防御

针对此隐私攻击(及更多攻击!)的最佳防御是在您的网站上设置HTTP严格传输安全(HSTS),并在此过程中提交您的域名进行HSTS预加载。如果预加载,HSTS有效防止浏览器通过不安全通道访问您域上的资源。但是,如果您需要(出于某些可疑原因)维护对该域上不安全源的浏览器访问,HSTS显然不是您的选择。另一种更细粒度的防御包括更改要保护的Cookie的名称并使用某些Cookie名称前缀。这将起作用,因为浏览器不允许不安全源设置带前缀的Cookie。__Secure- Cookie名称前缀就足够了,但您也可以选择名称令人困惑但更安全的__Host- Cookie名称前缀,如果您不觉得它太限制性。但是,如果相关Cookie用于身份验证,请记住更改其名称将有效地注销所有用户。

结论

信息安全的一个比喻是CIA(机密性、完整性、可用性)三元组。在三个方面之间取得平衡是一项困难的练习,因为通常无法改变其中任何一个而不对其他两个产生不利影响。严格安全Cookie也不例外:它用一些机密性换取了完整性。在Cookie真正成为源绑定的遥远未来之前,Web可能仍然受到Cookie缺陷的困扰。

致谢

感谢Ankur Sundara,他慷慨同意在发布前审阅本文的草稿。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计