原文链接(需越墙):https://developers.google.com/web/updates/2018/02/meltdown-spectre原文作者:Surma 最后更新时间: 2018-2-7
译者:西楼听雨
(转载请注明出处)
Overview 引言
On January 3rd Project Zero revealed vulnerabilities in modern CPUs that a process can use to read (at worst) arbitrary memory — including memory that doesn’t belong to that process. These vulnerabilities have been named Spectre and Meltdown. What is Chrome doing to help keep the web secure, and what should web developers do for their own sites?
1月3号,Project Zero 揭露了在现代 CPU 中存在的一些漏洞,他们可以允许进程读取任意内存(最糟糕情况)——包括那些本身不属于它的内存。 这些漏洞被命名为 Spectre 和 Meltdown。那么,Chrome 该做些什么来保障 Web 的安全呢?Web 开发者们又该为自己的网站做些什么呢?
TL; DR 结论("太长,不看了")
As a user browsing the web, you should make sure you keep your operating system and your browser updated. In addition, Chrome users can consider enabling Site Isolation.
作为一名浏览网页的用户,你应该确保你操作系统以及浏览器时刻保持最新版本。另外,Chrome 的用户可以考虑把“站点隔离”打开。
If you are a web developer, the Chrome team advises:
- Where possible, prevent COOKIEs from entering the renderer process' memory by using the SameSite and HTTPOnly COOKIE attributes, and by avoiding reading from document.COOKIE.
- Make sure your MIME types are correct and specify an
X-Content-Type-Options: nosniff
header for any URLs with user-specific or sensitive content, to get the most out of cross-site document blocking for users who have Site Isolation enabled. - Enable Site Isolation and let the Chrome team know if it causes problems for your site.
如果你是一名 Web 开发者,Chrome 团队建议:
- 在任何可能的地方,通过设置 COOKIE 的 SameSite 和 HTTPOnly 属性,并避免读取 document.COOKIE,来防止 COOKIEs 进入渲染进程的内存。
- 确保 MIME 类型正确,并对任何与特定用户相关或包含敏感内容的 URL 指定一个
X-Content-Type-Options: nosniff
响应头,以此来为那些开启了站点隔离的用户提供最大的跨站点阻隔好处。 - 启用站点隔离,并让 Chrome 团队知晓这样是否会给你的站点带来一些问题。
If you are wondering why these steps help, read on!
如果你对上面这些为什们有用感兴趣,请继续往下读!
The risk 风险
There have been a wide variety of explanations of these vulnerabilities, so I am not going to add yet another one. If you are interested in how these vulnerabilities can be exploited, I recommend taking a look at the blog post by my colleagues from the Google Cloud team.
现在已经有很多对这些漏洞的各种解释了,所以,我就不再重复了。如果你对它们可以被如何拿来利用感兴趣,我推荐你看一下我的谷歌云团队的同事写的这篇博客文章。
Both Meltdown and Spectre potentially allow a process to read memory that it is not supposed to be able to. Sometimes, multiple documents from different sites can end up sharing a process in Chrome. This can happen when one has opened the other using window.open
, or , or iframes. If a website contains user-specific data, there is a chance that another site could use these new vulnerabilities to read that user data.
Meltdown 和 Spectre 都潜在具备让一个进程读取本意不被允许读取的内存的可能。而在 Chrome 中,有时来自不同站点的多个文档是可能共享一个进程的。这种情况可能会发生在,一个站点使用window.open
或者 ,或者
iframes
来打开另一个站点的时候。(这样的话,)如果某个网站含有特定于用户的数据,那么其他站点就有机会利用这些新漏洞来读取用户数据。
Mitigations 缓解措施
There are multiple efforts the Chrome and V8 engineering team is deploying to mitigate this threat.
Chrome 和 V8 工程的团队正在尽各种努力发布部署,来缓解这种威胁。
Site Isolation 站点隔离
The impact of successfully exploiting Spectre can be greatly reduced by preventing sensitive data from ever sharing a process with attacker-controlled code. The Chrome team has been working on a feature to achieve this called “Site Isolation”:
如果我们可以彻底防止敏感数据与攻击者控制的代码所在的进程进行共享,那么我们就可以极大的减轻 Spectre 被成功利用后的影响。Chrome 团队已经在为一项可以实现这种效果的新特性而努力:
“Websites typically cannot access each other's data inside the browser[...]. Occasionally, security bugs are found in this code and malicious websites may try to bypass these rules to attack other websites. [...] Site Isolation offers a second line of defense to make such attacks less likely to succeed. It ensures that pages from different websites are always put into different processes, each running in a sandbox that limits what the process is allowed to do.”
“通常,在浏览器中,网站与网站之间是不能访问对方的数据的……。偶尔,也会有安全性bug可能会尝试绕过这些规则来攻击其他网站。……'站点隔离'提供了对制造这种攻击发生的第二道防线,以此减轻其发生的可能。它确保了来自不同网站的页面总是被置于不同的进程中,各自运行在一个限制其可访问内容的沙盒内。“
Site Isolation has not been enabled by default yet as there are a couple of known issues and the Chrome team would like as much field testing as possible. If you are a web developer, you should enable Site Isolation and check whether your site remains functional. If you’d like to opt-in now, enable chrome://flags#enable-site-per-process
. If you find a site that doesn’t work, please help us by filing a bug and mention that you have Site Isolation enabled.
"站点隔离"目前还没有在默认情况下开启,因为现在还有一些已知的问题,而且 Chrome 团队也希望对其进行尽可能多的测试。作为一名 Web 开发者,你应该把它开启并检查下站点是否仍然正常。假如你想现在就开启,请打开 chrome://flags#enable-site-per-process
(这个 flag)。如果开启之后你发现某个站点不能正常工作,请填写一个 bug 并提及你已经打开了"站点隔离",以此给予我们帮助。
Cross-site document blocking 跨站文档阻隔
Even when all cross-site pages are put into separate processes, pages can still legitimately request some cross-site subresources, such as images and Javascript. To help prevent sensitive information from leaking this information, Site Isolation includes a “cross-site document blocking” feature that limits which network responses are delivered to the renderer process.
即便是把所有的跨站页面置入分离的进程中,页面仍然可以合法地请求一些跨站的资源,例如,图片和Javascript。为了防止敏感信息从此处暴露,“站点隔离”包含了一个叫做“跨站文档阻隔”的特性,它可以控制网络响应是否可以进入渲染进程。
A website can request two types of data from a server: “documents” and “resources”. Here, documents are HTML, XML, JSON and TXT files. A website is able to receive documents from its own domain or from other domains with permissive CORS headers. Resources include things like images, Javascript, CSS and fonts. Resources can be included from any site.
网站可以从服务器请求两种类型的数据:“文档”和“资源”。在这里所谓的“文档”指的是 HTML,XML,JSON 和 TXT 文件。一个网站可以接收来自同域下的文档,也可以接收来自跨域的 CORS 头部为允许的文档。而所谓的“资源”则包含有图片,Javascript,CSS,字体,他们可以被任何站点所引用。
The cross-site document blocking policy prevents a process from receiving “documents” from other origins if:
- They have an HTML, XML, JSON, or text/plain MIME type, and
- They have either a "X-Content-Type-Options: nosniff" HTTP response header, or a quick content analysis (“sniffing”) confirms that the type is correct
- CORS doesn’t explicitly allow access to the document
跨站文档阻隔政策会在以下情况下阻隔来自其他域下“文档”的接收:
- “文档”是 HTML,XML,JSON,或者
text/plain
MIME 类型,且 - 要么“文档”的响应头部有一个 "X-Content-Type-Options: nosniff",要么在浏览器的快速内容分析中(“sniffing”)确认了类型的正确。
- 没有得到 CORS 显式地允许
Documents that are blocked by this policy are presented to the process as empty, although the request still happens in the background.
被这个政策阻隔的这些文档会以空白的形式进入进程,虽然请求实际还在后台进行。
For example: Imagine an attacker creating an tag that includes a JSON file with sensitive data, like
. Without Site Isolation, the contents of the JSON file would make it to the renderer process’s memory, at which point the renderer notices that it is not a valid image format and doesn’t render an image. With Spectre, however, there is now a way to potentially read that chunk of memory. Cross-site document blocking would prevent the contents of this file from ever entering the memory of the process the renderer is running in because the MIME type is blocked by cross-site document blocking.
例如:想象一个攻击者,他创建了一个标签,而这个标签指向了一个包含敏感数据的JSON文件,如
。如果没有站点隔离,那么这个JSON文件的内容就会进入渲染进程的内存,此时渲染进程会注意到它不是一个正确的图片格式,并放弃把它渲染为一张图片。然而,这对于 Spectre 来说,现在就有了一条可以读取这块内存块的潜在机会了。跨站文档阻隔政策就可以防止这个JSON文件进入渲染器进程的内存,因为仅通过它的 MIME 类型,跨站文档阻隔功能就会将其阻隔。
According to user metrics, there are a lot of Javascript and CSS files that are delivered with text/html
or text/plain
MIME types. To avoid blocking resources that are accidentally marked as documents, Chrome attempts to sniff the response to ensure the MIME type is correct. This sniffing is imperfect, so if you are sure that you are setting the correct Content-Type
headers on your website, the Chrome team recommends adding the X-Content-Type-Options: nosniff
header to all your responses.
按照用户数据矩阵的结果,有许多 Javascript 和 CSS 文件是以 text/html
或者 text/plain
MIME 类型来传输的。为了防止哪些不经意被标志为了文档类型的资源被阻隔,Chrome 会尝试对响应进行嗅探,以此确保 MIME 类型是正确的。这种尝试存在缺点,所以,如果你肯定你所有的资源都设置了正确的 Content-Type 头的话,Chrome 团队建议再为所有响应添加一个 X-Content-Type-Options: nosniff
头。
If you want to try cross-site document blocking, opt-in to Site Isolation as described above.
如果你也想尝试一下跨站文档阻隔,请看上面“站点隔离”一节来开启它。
SameSite COOKIEs 同站 COOKIE
Let’s go back to the example above: . This only works if yourbank.com has stored a COOKIE that automatically logs the user in. COOKIEs typically get sent for all requests to the website that sets the COOKIE — even if the request is made by a third party using an
tag. SameSite COOKIEs are a new attribute that specify that a COOKIE should only be attached to a request that originates from the same site, hence the name. Sadly, at the time of writing, only Chrome and Firefox 58+ support this attribute.
回到上面的例子:。其实它只在 yourbank.com 保存了用户登陆后会自动保存的 COOKIE 时才起作用。通常 COOKIE 都会伴随着所有请求一起发送给设置它的网站——即便请求是由第三方发起的,例如上面的
。SameSite 是一个新的 COOKIE 属性,它可以指定一个 COOKIE 只在请求是由同一个站点的页面发起的时候才伴随发送,这也是它名字的由来。不过遗憾的时,在本文编写的时间点,还只有 Chrome 和 Firefox 58+ 支持这个属性。
HTTPOnly and document.COOKIE
If your site's COOKIEs are only used server-side, not by client Javascript, there are ways you can stop the COOKIE's data from entering the renderer process. You can set the HTTPOnly
COOKIE attribute, which explicitly prevents the COOKIE from being accessed through client side script on supported browsers, such as Chrome. If setting HTTPOnly
isn't possible, you can help limit the exposure of loading COOKIE data to the rendered process by not reading document.COOKIE
unless absolutely necessary.
如果你网站的 COOKIE 只在服务端用到,客户端没有用到,那么这有多种方式可以防止 cooike 数据进入渲染进程。你可以给 COOKIE 设置 HTTPOnly
属性,它被所有浏览器所支持(如Chrome),这样可以显式地防止客户端脚本访问 COOKIE。 如果无法设置 HTTPOnly
,你也只需要确保不读取 document.COOKIE
,除非绝对有必要, 以此来限制对加载 COOKIE 数据的时的暴露。
Open External Links Using rel="noopener" 使用 rel="noopener" 来打开外部链接
When you link to another page using target="_blank"
, the opened page has access to your window
object, can navigate your page to a different URL, and without Site Isolation will be in the same process as your page. To better protect your page, links to external pages that open in a new window should always specify rel="noopener"
.
如果你使用 target="_blank" 链接其他页面,那么打开后的目标页面是可以访问到你的 window 对象的,然后可以把你的页面导航到另外一个URL,并且如果没有站点隔离的话,这个页面将会和你的页面在同一个进程里面。所以,为了更好地保护你的页面,对于需要在一个新窗口打开的外部页面链接,你应该始终为其指定 rel="noopener"
。
High-resolution timers 高精度计时器
To exploit Meltdown or Spectre, an attacker needs to measure how long it takes to read a certain value from memory. For this, a reliable and accurate timer is needed.
想要利用 Meltdown 和 Spectre,攻击者必须测量出从内存读取某个值的耗时。而这种测量,必须借助一个高可靠、高精度的计时器。
One API the web platform offers is performance.now()
which is accurate to 5 microseconds. As a mitigation, all major browsers have decreased the resolution of performance.now()
to make it harder to mount the attacks.
Web 平台提供的其中一个 API 是 performance.now() ,它可以精确到5微妙。为了缓解攻击,所有的浏览器都降低了这个 API 的精度,以使得它很难成为攻击的入口。
Another way to get a high-resolution timer is to use a SharedArrayBuffer. The buffer is used by a dedicated worker to increment a counter. The main thread reads this counter and uses that as a timer. For the time being browsers have decided to disable SharedArrayBuffer until other mitigations are in place.
另外一种获取高精度计时器的方式是使用 SharedArrayBuffer。例如,用一个专门的 worker 来增加一个计数变量,然后主线程读取这个变量,(记录读取耗时),以此当作计时器。目前所有浏览器都已经决定准备禁用 SharedArrayBuffer,直到其他措施到位。
V8
To exploit Spectre, a specifically crafted sequence of CPU instructions is needed. The V8 team has implemented mitigations for known attack proofs of concept, and is working on changes in TurboFan, their optimizing compiler, that make its generated code safe even when these attacks are triggered. However, these code generation changes may come at a performance penalty.
要利用 Spectre,必须要有一个精心准备的 CPU 指令序列。V8 团队对一些已知的理论上可能的攻击采取了缓解措施,也在努力对 TurboFan 做出改变,优化他们的编译器,以此保证代码的生成安全,即便是发生在攻击的时候。不过,这些代码生成的改变会带来性能上的代价。