内容简介:At Mozilla, we want the web to be capable of running high-performance applications so that users and content authors can choose the safety, agency, and openness of the web platform. One essential low-level building block for many high-performance applicati
At Mozilla, we want the web to be capable of running high-performance applications so that users and content authors can choose the safety, agency, and openness of the web platform. One essential low-level building block for many high-performance applications is shared-memory multi-threading. That’s why it was so exciting to deliver shared memory to JavaScript and WebAssembly in 2016. This provided extremely fast communication between threads.
However, we also want the web to be secure from attackers. Keeping users safe is paramount, which is why shared memory and high-resolution timers were effectively disabled at the start of 2018 , in light of Spectre . Unfortunately, Spectre-attacks are made significantly more effective with high-resolution timers. And such timers can be created with shared memory. (This is accomplished by having one thread increment a shared memory location in a tight loop that another thread can sample as a nanosecond-resolution timer.)
Back to the drawing board
Fundamentally, for a Spectre attack to work, an attacker and victim need to reside in the same process. Like most applications on your computer, browsers used to use a single process. This would allow two open sites, say attacker.example
and victim.example
, to Spectre-attack each other’s data as well as other data the browser might keep such as bookmarks or history. Browsers have long since become multi-process. With Chrome’s Site Isolation and Firefox’sProject Fission, browsers will isolate each site
into its own process. This is possible due to the web platform’s retrofittedsame-origin policy.
Unfortunately, isolating each site into its own process is still not sufficient for these reasons:
-
The same-origin policy has a number of holes, two of which strongly informed our thinking during the design process:
-
attacker.example
can fetch arbitraryvictim.example
resources intoattacker.example
’s process, e.g., through the<img>
element. -
Due to the existence of
document.domain
, the minimal isolation boundary is a site (roughly the scheme and registrable domain of a website’s host) and not an origin (roughly a website’s scheme, host, and port).
-
- At this point, we don’t know if it’s feasible to isolate each site into its own process across all platforms. It is still a challenging endeavor on mobile. While possibly not a long-term problem, we would prefer a solution that allows reviving shared memory on mobile soon .
Distilling requirements
We need to address the issues above to revive shared memory and high-resolution timers. As such, we have been working on a system that meets the following requirements:
<img>
Due to these requirements, the system must provide an opt-in mechanism. We cannot forbid websites from fetching cross-origin subresources, as this would not be backwards compatible. Sadly, restricting document.domain
is not backwards compatible either. More importantly, it would be unsafe to allow a website to embed cross-origin documents via an <iframe>
element and have those cross-origin resources end up in the same process without opting in.
Cross-origin isolated
New headers
Together with others in the WHATWG community, we designed a set of headers that meet these requirements.
The
Cross-Origin-Opener-Policy
header allows you to process-isolate yourself from attackers. It also has the desirable effect that attackers cannot have access to your global object if they were to open you in a popup. This prevents XS-Leaks
and various navigation attacks. Adopt this header even if you have no intention of using shared memory!
The
Cross-Origin-Embedder-Policy
header with value require-corp
tells the browser to only allow this document to fetch cross-origin subresources from consenting websites. Technically, the way that this works is that those cross-origin resources need to specify the
Cross-Origin-Resource-Policy
header with value cross-origin
to indicate consent.
Impact on documents
If the Cross-Origin-Opener Policy
and Cross-Origin-Embedder-Policy
headers are set for a top-level document with the same-origin
and require-corp
values respectively, then:
- That document will be cross-origin isolated.
-
Any descendant documents that also set
Cross-Origin-Embedder-Policy
torequire-corp
will be cross-origin isolated. (Not setting it results in a network error.) -
Any popups these documents open will either be cross-origin isolated or will not have a direct relationship with these documents. This is to say that there is no direct access through
window.opener
or equivalent (i.e., it’s as if they were created usingrel="noopener"
).
A document that is cross-origin isolated will have access to shared memory, both in JavaScript and WebAssembly. It will only be able to share memory with same-origin documents and dedicated workers in the same “tab” and its popups (technically, same-origin agents in a single browsing context group
). It will also have access to the highest-resolution performance.now()
available. Evidently, it will not have access to a functional document.domain
.
The way these headers ensure mutual consent between origins gives browsers the freedom to put an entire website into a single process or put each of the origins into their own process, or something in between. While process-per-origin would be ideal, this is not always feasible on all devices. So having everything that is pulled into these one-or-more processes consent is a decent middle ground.
Safety backstop
We created a safety backstop to be able to deal with novel cross-process attacks. And used an approach that avoids having to disable shared memory entirely to remain web compatible.
The result is Firefox’s
JSExecutionManager
. This allows us to regulate the execution of different JavaScript contexts with relation to each other. The JSExecutionManager
can be used to throttle CPU and power usage by background tabs. Using the JSExecutionManager
, we created a dynamic switch ( dom.workers.serialized-sab-access
in about:config
) that prevents all JavaScript threads that share memory from ever running code concurrently, effectively executing these threads as if on a single-core machine. Because creating a high-resolution timer using shared memory requires two threads to run simultaneously, this switch effectively prevents the creation of a high-resolution timer without breaking websites.
By default, this switch is off, but in the case of a novel cross-process attack, we could quickly flip it on. With this switch as a backstop, we can feel confident enabling shared memory in cross-origin isolated websites even when considering unlikely future worst-case scenarios.
Acknowledgments
Many thanks to Bas Schouten and Luke Wagner for their contributions to this post. And also, in no particular order, many thanks to Nika Layzell, Tom Tung, Valentin Gosu, Eden Chuang, Jens Manuel Stutte, Luke Wagner, Bas Schouten, Neha Kochar, Andrew Sutherland, Andrew Overholt, 蔡欣宜 (Hsin-Yi Tsai), Perry Jiang, Steve Fink, Mike Conca, Lars Thomas Hansen, Jeff Walden, Junior Hsu, Selena Deckelmann, and Eric Rescorla for their help getting this done in Firefox!
很遗憾的说,推酷将在这个月底关闭。人生海海,几度秋凉,感谢那些有你的时光。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。