At the end of August 2019 we expressed an intent to prototype the
re-enablement of SharedArrayBuffer. Many bugs and design
iterations later, we’re happy to announce that it’s now ready. We
would like to ship this in Firefox 79 or 80.
To do this in a post-Spectre-safe manner we have worked with others
to add the cross-origin isolated primitive to the web platform, which
provides sites that opt into it with their own process that cannot
pull in non-consenting external resources. In that process they get
to use high-resolution clocks and shared memory.
To address novel attacks, we have added the ability to throttle
implementation work, we could also use this capability to reduce
resource consumption and improve battery life, e.g., by enabling it
for background tabs.
Here’s a summary of the changes:
SharedArrayBuffer to release, although globalThis.SharedArrayBuffer
returns undefined as long as the cross-origin isolated primitive is
false. This included support for the shared:true parameter of
* As part of this intent we’ll ship the Cross-Origin-Opener-Policy
and Cross-Origin-Embedder-Policy headers, that when set to the
same-origin and require-corp values respectively, for a top-level
document, enable its browsing context group to be cross-origin
isolated. (Cross-Origin-Opener-Policy also helps sites close a
security hole in the web platform by preventing themselves from
being opened in a popup an attacker might control.)
If a document is cross-origin isolated:
* globalThis.crossOriginIsolated will return true.
* globalThis.SharedArrayBuffer will no longer return undefined.
* postMessage() can be used to message SharedArrayBuffer objects,
restricted to the agent cluster (the smallest unit a browser
could isolate in a process) it was created in.
* Agent clusters within a cross-origin isolated browsing context
group are keyed on origin rather than site: this means that 1)
shared memory is bound to a single origin (postMessage()’ing
elsewhere results in a messageerror) and 2) document.domain is
ineffective (it returns just before changing the origin, for
maximum compatibility with existing libraries that reportedly set
it a lot, but don’t really care if it works). (With Fission this
would allow us to use actual processes at the origin boundary
too, but we have not looked into that much thus far.)
* Timers are no longer throttled, including performance.now().
Chrome plans to match this model by August 2020 for Android, March
2021 for all except sites that opt-out, and May 2021 for all without
It’s being standardized primarily in the Fetch and HTML standards,
through a number of pull requests that are close to done:
(timers; not much progress
on this unfortunately; timers in general are a somewhat poorly
defined piece of infrastructure)
Shipping bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1619649
(Following this work we plan to change the header parsers from strict
byte sequence comparisons to using structured headers, which will
also pave the way for adding reporting functionality. We also plan to
eventually support cross-origin isolated for shared and service
workers and roll all of this out on mobile.)
In no particular order, many thanks to Nika, Tom, Valentin, Eden,
Jens, Luke, Bas, Neha, Andrew (x2), Hsin-Yi, Perry, Steve, Mike,
Lars Thomas, Jeff, Junior, Selena, Yaron, and Eric for their help
getting this done in Firefox!