融化/《Spectre》

概览

1 月 3 日,Project Zero 揭示了现代 CPU 中存在漏洞,最坏的情况下,进程可利用这些漏洞读取任意内存(包括不属于该进程的内存)。这些漏洞被命名为 SpectreMeltdown。Chrome 正在采取哪些措施来确保网络安全?网络开发者应该如何保护自己的网站?

团队负责人;灾难恢复

作为浏览网页的用户,您应确保及时更新操作系统和浏览器。此外,Chrome 用户可以考虑启用网站隔离

如果您是 Web 开发者Chrome 团队建议

  • 请尽可能使用 SameSiteHTTPOnly Cookie 属性,并避免从 document.cookie 读取数据,以防止 Cookie 进入渲染程序进程的内存。
  • 请确保您的 MIME 类型正确无误,并为包含用户特定内容或敏感内容的所有网址指定 X-Content-Type-Options: nosniff 标头,以便针对已启用网站隔离功能的用户充分利用跨源读取屏蔽功能。
  • 请启用网站隔离,并告知 Chrome 团队这是否会为您的网站带来问题。

如果您想知道为什么这些步骤有帮助,请继续阅读下文!

风险

关于这些漏洞的说明五花八门,我不打算再补充一个。如果您有兴趣了解如何利用这些漏洞,建议您阅读 Google Cloud 团队的同事撰写的博文

Meltdown 和 Spectre 都可能允许进程读取其本不该能够读取的内存。有时,来自不同网站的多个文档 最终可能会在 Chrome 中共享一个进程当某个页面使用 window.open<a href="..." target="_blank"> 或 iframe 打开另一个页面时,可能会发生这种情况。如果某个网站包含用户特定数据,其他网站就有可能利用这些新漏洞读取相应用户数据。

缓解措施

Chrome 和 V8 工程团队正在采取多种措施来减轻这种威胁。

网站隔离

通过防止敏感数据与攻击者控制的代码共享进程,可以大大降低成功利用 Spectre 的影响。Chrome 团队一直在开发一项称为“网站隔离”的功能来实现这一点:

由于存在一些已知问题,Chrome 团队希望进行尽可能多的现场测试,因此网站隔离功能默认处于未启用状态。如果您是 Web 开发者,则应启用网站隔离并检查您的网站是否仍可正常运行。如果您想立即选择启用,请启用 chrome://flags#enable-site-per-process。如果您发现某个网站无法正常运行,请提交 bug 并向我们说明您已启用网站隔离功能。

跨网站文档拦截

即使所有跨网站网页都放入单独的进程中,网页仍然可以合法地请求一些跨网站子资源,例如图片和 JavaScript。为了防止敏感信息泄露,网站隔离功能包含“跨网站文档拦截”功能,用于限制向渲染程序进程传递哪些网络响应。

网站可以向服务器请求两种类型的数据:“文档”和“资源”。在这里,文档包括 HTML、XML、JSON 和文本文件。网站能够接收来自自己的网域或具有宽松 CORS 标头的其他网域的文档。资源包括图片、JavaScript、CSS 和字体等。任何网站的资源都可以包含在内。

如果出现以下情况,跨网站文档拦截政策会阻止进程接收来自其他来源的“文档”:

  1. 它们具有 HTML、XML、JSON 或 text/plain MIME 类型,并且
  2. 它们具有 X-Content-Type-Options: nosniff HTTP 响应标头或用于确认类型是否正确的快速内容分析(“嗅探”功能)
  3. CORS 未明确允许访问文档

被此政策屏蔽的文档将作为空文件呈现给进程,但请求仍在后台进行。

例如:假设攻击者创建一个 <img> 标记,其中包含一个包含敏感数据的 JSON 文件(例如 <img src="https://yourbank.com/balance.json">)。如果没有网站隔离,JSON 文件的内容会进入渲染程序进程的内存,此时渲染程序会注意到它不是有效的图片格式,并且不会渲染图片。不过,借助 Spectre,现在有办法读取该内存块。跨网站文档屏蔽会阻止此文件的内容进入运行渲染程序的进程的内存,因为 MIME 类型会被跨网站文档屏蔽屏蔽。

根据用户指标,大量 JavaScript 和 CSS 文件随 text/htmltext/plain MIME 类型一起提供。为避免屏蔽意外标记为文档的资源,Chrome 会尝试嗅探响应,以确保 MIME 类型正确无误。此嗅探功能并不完善,因此如果您确定在网站上设置了正确的 Content-Type 标头,Chrome 团队建议您将 X-Content-Type-Options: nosniff 标头添加到您的所有响应中。

如果您想尝试跨网站文档屏蔽功能,请按上文所述选择启用网站隔离功能。

SameSite 个 Cookie

我们再回来看上面的示例:<img src="https://yourbank.com/balance.json">。只有当 yourbank.com 存储了可自动让用户登录的 Cookie 时,此方法才适用。通常,系统会向设置 Cookie 的网站发出的所有请求发送 Cookie,即使请求是由使用 <img> 标记的第三方发出的也是如此。SameSite Cookie 是一个新属性,用于指定 Cookie 只能附加到来自同一网站的请求,因此名称如此。遗憾的是,在撰写本文时,只有 Chrome 和 Firefox 58 及更高版本支持此属性

HTTPOnly”和“document.cookie

如果您的网站 Cookie 仅在服务器端(而非客户端 JavaScript)使用,您可以通过多种方式阻止 Cookie 的数据进入渲染程序进程。您可以设置 HTTPOnly Cookie 属性,该属性明确阻止在受支持的浏览器(例如 Chrome)上通过客户端脚本访问 Cookie。如果无法设置 HTTPOnly,除非绝对必要,否则您可以不读取 document.cookie,从而帮助限制在呈现进程中加载 Cookie 数据。

当您使用 target="_blank" 链接到另一个页面时,打开的页面可以访问您的 window 对象,可以将页面导航到其他网址,并且如果不使用网站隔离功能,将与您的页面处于相同的进程。为了更好地保护您的网页,指向在新窗口中打开的外部网页的链接应始终指定 rel="noopener"

高分辨率计时器

为了利用 Meltdown 或 Spectre,攻击者需要衡量从内存读取特定值所需的时间。为此,需要一个可靠且准确的计时器。

Web 平台提供的一个 API 是 performance.now(),其精确到 5 微秒。作为缓解措施,所有主流浏览器都降低了 performance.now() 的分辨率,使装载攻击变得更加困难。

获取高分辨率计时器的另一种方法是使用 SharedArrayBuffer。缓冲区供专用工作器用于递增计数器。主线程会读取此计数器并将其用作计时器。目前,浏览器已决定停用 SharedArrayBuffer,直至其他缓解措施落实为止。

V8

为了利用 Spectre,需要一个特别设计的 CPU 指令序列。V8 团队为已知的攻击概念证明实施了缓解措施,并正在对他们的优化编译器 TurboFan 进行更改,使生成的代码即使在触发这些攻击时也能安全。但是,这些代码生成变更可能会降低性能。

保障网络安全

关于 Spectre 和 Meltdown 的发现及其影响,存在很多不确定性。我希望本文能帮助您了解 Chrome 和 V8 团队为保障网络平台安全所做的努力,以及网络开发者如何利用现有的安全功能提供帮助。如果您有任何疑问,请随时通过 Twitter 与我联系。