Meltdown/Spectre 在 Web 开发中的防范(中英)

原文连接(需越墙)https://developers.google.com/web/updates/2018/02/meltdown-spectre

原文做者:Surma  最后更新时间: 2018-2-7
php

译者:西楼听雨html

(转载请注明出处)git


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?github

1月3号,Project Zero 揭露了在现代 CPU 中存在的一些漏洞,他们能够容许进程读取任意内存(最糟糕状况)——包括那些自己不属于它的内存。 这些漏洞被命名为 Spectre Meltdown。那么,Chrome 该作些什么来保障 Web 的安全呢?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

做为一名浏览网页的用户,你应该确保你操做系统以及浏览器时刻保持最新版本。另外,Chrome 的用户能够考虑把“站点隔离”打开。json

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 <a href="..." target="_blank">, 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 或者 <a href="..." target="_blank">,或者 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:

  1. They have an HTML, XML, JSON, or text/plain MIME type, and
  2. They have either a "X-Content-Type-Options: nosniff" HTTP response header, or a quick content analysis (“sniffing”) confirms that the type is correct
  3. CORS doesn’t explicitly allow access to the document

跨站文档阻隔政策会在如下状况下阻隔来自其余域下“文档”的接收:

  1. “文档”是 HTML,XML,JSON,或者 text/plain MIME 类型,且
  2.  要么“文档”的响应头部有一个 "X-Content-Type-Options: nosniff",要么在浏览器的快速内容分析中(“sniffing”)确认了类型的正确。
  3.  没有获得 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 <img> tag that includes a JSON file with sensitive data, like <img src="https://yourbank.com/balance.json">. 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.

例如:想象一个攻击者,他建立了一个<img>标签,而这个标签指向了一个包含敏感数据的JSON文件,如<img src="https://yourbank.com/balance.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/plainMIME 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: <img src="https://yourbank.com/balance.json">. 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 <img> 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.

回到上面的例子:<img src="https://yourbank.com/balance.json">。其实它只在 yourbank.com 保存了用户登录后会自动保存的 cookie 时才起做用。一般 cookie 都会伴随着全部请求一块儿发送给设置它的网站——即使请求是由第三方发起的,例如上面的 <img>。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 作出改变,优化他们的编译器,以此保证代码的生成安全,即使是发生在攻击的时候。不过,这些代码生成的改变会带来性能上的代价。

相关文章
相关标签/搜索