SharedArrayBuffer and Cross-Origin Isolation in JS
SharedArrayBuffer enables high-performance
multithreading by allowing multiple JavaScript workers to share
identical memory allocations. However, due to hardware-level
side-channel vulnerabilities such as Spectre, modern web browsers
restrict access to SharedArrayBuffer unless the execution
context is “cross-origin isolated.” This security model fundamentally
changes how JavaScript applications handle multithreading, integrate
third-party resources, and configure server-side headers.
Why Cross-Origin Isolation Is Required
The Spectre vulnerability demonstrated that malicious actors could
use shared memory buffers and high-resolution timers to measure CPU
cache timing differences, allowing them to read sensitive data across
execution contexts. Because SharedArrayBuffer allows
simultaneous reads and writes across threads without message-passing
latency, it can function as a high-precision timer suitable for
side-channel attacks.
To eliminate this threat without permanently removing shared memory capabilities, browser vendors introduced cross-origin isolation to ensure that a page cannot access sensitive cross-origin data through side-channel exploitation.
Enabling the Isolated Environment
To use SharedArrayBuffer, a website must serve specific
HTTP response headers on the main document:
Cross-Origin-Opener-Policy: same-origin(COOP): Isolates the browsing context group exclusively to same-origin documents. Other origins cannot maintain references to the page viawindow.opener.Cross-Origin-Embedder-Policy: require-corporcredentialless(COEP): Ensures that the document can only load resources that explicitly grant permission to be loaded in an isolated environment.
When these headers are configured correctly,
window.crossOriginIsolated (or
self.crossOriginIsolated in Web Workers) evaluates to
true, unlocking SharedArrayBuffer and other
restricted APIs.
Impact on JavaScript Development
Cross-origin isolation impacts several core aspects of modern web development:
- WebAssembly Multithreading: WebAssembly threads
depend directly on
SharedArrayBuffer. High-performance libraries—such as FFmpeg.wasm, TensorFlow.js, and 3D rendering engines—cannot utilize multiple CPU cores unless isolation is active. - Thread Synchronization: The
Atomicsobject (Atomics.wait,Atomics.notify) requires aSharedArrayBuffer. Without isolation, concurrent algorithms that rely on mutexes or shared queues cannot function. - Timer Precision: Browsers reduce the precision of
performance.now()in non-isolated contexts to limit side-channel risk. Cross-origin isolation allows browsers to restore full-precision timers. - Memory Measurement: Diagnostic APIs like
performance.measureUserAgentSpecificMemory()are strictly gated behind cross-origin isolation to prevent memory layout leakage.
The Cost: Integration with Third-Party Resources
While cross-origin isolation secures shared memory, it introduces
strict limitations on external assets. Under a strict COEP policy
(require-corp), any embedded image, script, stylesheet, or
iframe hosted on a different domain must serve a
Cross-Origin-Resource-Policy (CORP) header or permit CORS
access.
This creates significant challenges when integrating third-party dependencies, including: * Analytics and Ad Networks: External scripts that do not serve CORP headers are blocked. * Embedded Iframes: Third-party widgets (e.g., payment gateways, social embeds) cannot be framed unless the provider explicitly supports isolation headers. * Media and CDN Hosting: All external CDNs must be configured to return appropriate CORS or CORP response headers.
To ease adoption, developers can use
Cross-Origin-Embedder-Policy: credentialless, which allows
cross-origin resources without CORP headers to load by omitting
credentials like cookies and client certificates during the request.