融化/《Spectre》

概览

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

要点

作为浏览网页的用户,您应确保操作系统和浏览器始终保持最新状态。此外,Chrome 用户可以考虑启用网站隔离

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

  • 尽可能使用 SameSiteHTTPOnly Cookie 属性来防止 Cookie 进入渲染程序进程的内存,并避免从 document.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 或文本/纯文本 MIME 类型,并且
  2. 它们要么具有 X-Content-Type-Options: nosniff HTTP 响应标头,要么通过快速内容分析(“嗅探”)来确认类型正确无误
  3. CORS 未明确允许访问文档

被此政策屏蔽的文档会以空形式呈现给进程,但相应请求仍在后台进行。

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

根据用户指标,有许多使用 text/htmltext/plain MIME 类型的 JavaScript 和 CSS 文件。为避免屏蔽被意外标记为文档的资源,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 及更高版本支持此属性

HTTPOnlydocument.cookie

如果您网站的 Cookie 仅在服务器端使用,而不由客户端 JavaScript 使用,您可以阻止 Cookie 的数据进入渲染程序进程。您可以设置 HTTPOnly Cookie 属性,以明确禁止在受支持的浏览器(如 Chrome)上通过客户端脚本访问相应 Cookie。如果无法设置 HTTPOnly,您可以限制向呈现的进程加载 Cookie 数据,除非绝对必要,否则不读取 document.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 团队采取了哪些措施来确保网络平台安全,以及 Web 开发者如何利用现有的安全功能。如果您有任何疑问,请随时在 Twitter 上与我联系。