There is standardization work ongoing that enables developers to create
SharedArrayBuffer
objects again, but changes are needed in order to be use these across threads (i.e.,
postMessage()
for
SharedArrayBuffer
objects throws by default). These changes provide further isolation between sites and help reduce the impact of attacks with high-resolution timers, which can be created with shared memory.
Starting with Firefox 79, the features described in this document are enabled by default.
Chrome intends to implement similar restrictions.
As a baseline requirement, documents will need to be in a secure context .
For top-level documents, two headers will need to be set:
Cross-Origin-Opener-Policy
with
same-origin
as value (protects your origin from attackers)
Cross-Origin-Embedder-Policy
with
require-corp
as value (protects victims from your origin)
With these two headers set,
postMessage()
will no longer throw for
SharedArrayBuffer
objects and shared memory across threads is therefore available.
Nested documents and dedicated workers will need to set the
Cross-Origin-Embedder-Policy
header as well with the same value. No further changes are needed for same-origin nested documents and subresources. Same-site (but cross-origin) nested documents and subresources will need to set the
Cross-Origin-Resource-Policy
header with
same-site
as value. And their cross-origin (and cross-site) counterparts need to set the same header with
cross-origin
as value. Note that setting the
Cross-Origin-Resource-Policy
header to any other value than
same-origin
opens up the resource to potential attacks, such as
Spectre
.
注意,
Cross-Origin-Opener-Policy
header limits your ability to retain a reference to popups. Direct access between two top-level window contexts will essentially only work if they are same-origin and carry the same two headers with the same two values.
As a result of this newly required environment, there are a couple API implications:
Atomics
object is always available.
SharedArrayBuffer
objects are in principle always available, but unfortunately the constructor on the global object is hidden, unless the two headers mentioned above are set, for compatibility with web content. There is hope that this restriction can be removed in the future.
WebAssembly.Memory
can still be used to get an instance.
postMessage()
APIs will throw for
SharedArrayBuffer
objects. If they are set,
postMessage()
on
Window
objects and dedicated workers will function and allow for memory sharing.
postMessage()
throws,
self.crossOriginIsolated
is being standardized (a getter that returns a boolean;
true
if the headers are set), available in window and worker contexts.
The WebAssembly
Threads
proposal allows
WebAssembly.Memory
objects to be created with a new
shared
constructor flag. When this flag is set to
true
, the constructed
Memory
object can be shared between workers via
postMessage()
, just like
SharedArrayBuffer
, and the backing
buffer
of the
Memory
object is a
SharedArrayBuffer
. Therefore, the requirements listed above for sharing a
SharedArrayBuffer
between workers also apply to sharing a
WebAssembly.Memory
.
The WebAssembly Threads proposal also defines a new set of
atomic
instructions. Just as
SharedArrayBuffer
and its methods are unconditionally enabled (and only sharing between threads is gated on the new headers), the WebAssembly atomic instructions are also unconditionally allowed.
Cross-Origin-Opener-Policy
:
whatwg/html issue #3740
,
draft specification
.
Cross-Origin-Embedder-Policy
:
whatwg/html issue #4175
,
draft specification
.
Cross-Origin-Resource-Policy
:
standardized in Fetch
, new
cross-origin
value is part of the
Cross-Origin-Embedder-Policy
effort.
postMessage()
changes and
self.crossOriginIsolated
:
whatwg/html issue #4732
,
whatwg/html issue #4872
,
draft specification
.
SharedArrayBuffer
Function
Object
Object.prototype.__defineGetter__()
Object.prototype.__defineSetter__()
Object.prototype.__lookupGetter__()
Object.prototype.__lookupSetter__()
Object.prototype.hasOwnProperty()
Object.prototype.isPrototypeOf()
Object.prototype.propertyIsEnumerable()
Object.prototype.toLocaleString()
Object.prototype.toSource()
Object.prototype.toString()
Object.prototype.valueOf()
Object.setPrototypeOf()