Planned changes to shared memory

There is standardization work ongoing that enables developers to create SharedArrayBuffer objects again, but they will need to make some changes in order to be able to use these across threads (i.e., postMessage() throws by default). These changes enable further isolation between sites and help reduce the impact of attacks with high-resolution timers, which can be created with shared memory.

The Nightly release of Firefox 72 will soon have an experimental implementation of this enabled by default.

Chrome intends to implement similar restrictions.

New HTTP header bonanza

For top-level documents, two headers will need to be set:

  • Cross-Origin-Opener-Policy: same-origin (protects your origin from attackers)
  • Cross-Origin-Embedder-Policy: require-corp (protects victims from your origin)

Nested documents and dedicated workers will need to set the Cross-Origin-Embedder-Policy: require-corp header. Same-site (but cross-origin) nested documents and subresources will need to set the Cross-Origin-Resource-Policy: same-site header. And their cross-origin (and cross-site) counterparts need Cross-Origin-Resource-Policy: cross-origin.

Note that the 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.

API changes

As a result of this newly required environment, there are a couple of minor API implications:

  • SharedArrayBuffer objects are now always available, but cannot be serialized by default. This will enable more code sharing, gives JavaScript developers a non-detachable ArrayBuffer object, and allows APIs that do not enable the creation of high-resolution timers to take SharedArrayBuffer objects unconditionally.
  • Unless the two headers mentioned above are set, the various 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.
  • To avoid having to check whether 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.

WebAssembly Shared Memory

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.

Further reading