融化/《Spectre》

概览

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

要点

作为浏览网页的用户,您应确保操作系统和浏览器保持最新。此外,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. 它们的 MIME 类型为 HTML、XML、JSON 或 text/plain,并且
  2. 它们具有 X-Content-Type-Options: nosniff HTTP 响应标头,或者通过快速内容分析(“嗅探”)确认类型正确
  3. CORS 未明确允许访问文档

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

例如:假设攻击者创建了一个 <img> 标记,其中包含包含敏感数据(例如 <img src="https://yourbank.com/balance.json">)的 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 应仅附加到来自同一网站的请求,因此得名为 SameSite。遗憾的是,在撰写本文时,只有 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 与我联系。