How to Enable SharedArrayBuffer with COEP
This article explains what the Cross-Origin Embedder Policy (COEP)
is, why modern web browsers require it to establish a cross-origin
isolated environment, and how this mechanism safely re-enables
high-performance features like SharedArrayBuffer in
JavaScript. You will learn the security risks introduced by side-channel
attacks, how COEP prevents unauthorized resource loading, and the exact
HTTP response headers needed to unlock multi-threaded memory sharing
across Web Workers.
What is Cross-Origin Embedder Policy (COEP)?
Cross-Origin Embedder Policy (COEP) is an HTTP security header that forces a document to only load subresources (such as images, scripts, stylesheets, and iframes) that have explicitly granted permission to be loaded by that document.
COEP provides three directives:
Cross-Origin-Embedder-Policy: require-corp— Blocks any resource that does not provide an explicit Cross-Origin Resource Policy (CORP) header or a valid Cross-Origin Resource Sharing (CORS) response.Cross-Origin-Embedder-Policy: credentialless— Allows cross-origin resources to load without credentials (like cookies), bypassing the strict CORP requirement while maintaining isolation.Cross-Origin-Embedder-Policy: unsafe-none— The default state where resources are loaded without isolation checks.
When set to require-corp, a web page cannot accidentally
or maliciously embed cross-origin resources unless those resources
respond with Cross-Origin-Resource-Policy: cross-origin or
appropriate CORS headers.
The Security Problem: Spectre and SharedArrayBuffer
In JavaScript, SharedArrayBuffer allows multiple
execution threads (such as the main thread and Web Workers) to read and
write to the same shared memory location concurrently. While essential
for high-performance computing, WebAssembly multithreading, and media
processing, it also provides an extremely precise, shared clock.
With the discovery of the Spectre and
Meltdown hardware vulnerabilities, attackers
demonstrated that precise timing mechanisms could measure
microarchitectural CPU cache states to leak sensitive data across
security boundaries. Because browsers historically allowed documents to
embed cross-origin assets (like user profile images containing private
data) into the same process, an attacker could use
SharedArrayBuffer to execute side-channel attacks and read
unauthorized memory.
To protect user data, browser vendors disabled or heavily restricted
SharedArrayBuffer by default.
Cross-Origin Isolation: The Requirement for SharedArrayBuffer
To safely re-enable SharedArrayBuffer, browsers require
a webpage to enter a state called Cross-Origin
Isolation.
Cross-Origin Isolation guarantees that: 1. The document is strictly isolated in its own process and cannot be manipulated by cross-origin windows. 2. The document cannot read or embed arbitrary cross-origin resources into its process without explicit server permission.
This isolation is achieved by pairing COEP with the Cross-Origin Opener Policy (COOP).
How COEP Enables SharedArrayBuffer
Setting COEP satisfies the second condition of Cross-Origin Isolation by guaranteeing that no unauthorized data enters the document’s memory space.
To enable SharedArrayBuffer, your server must send the
following two response headers for the top-level HTML document:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-originprevents cross-origin popups or pages from interacting with your window object, placing your application in a dedicated browsing context group.Cross-Origin-Embedder-Policy: require-corpensures all assets embedded on your page have explicitly opted in via CORP or CORS.
Additionally, every cross-origin asset loaded by the page must include:
Cross-Origin-Resource-Policy: cross-origin
Verifying Cross-Origin Isolation in JavaScript
Once the required headers are configured on your server, you can
verify that the environment is properly isolated using the
crossOriginIsolated property in JavaScript:
if (window.crossOriginIsolated) {
// SharedArrayBuffer is available and safe to use
const sharedBuffer = new SharedArrayBuffer(1024);
const sharedArray = new Int32Array(sharedBuffer);
console.log("Cross-Origin Isolation active. SharedArrayBuffer initialized.");
} else {
console.warn("Cross-Origin Isolation is not active. SharedArrayBuffer is disabled.");
}If window.crossOriginIsolated evaluates to
true, the browser unlocks SharedArrayBuffer,
high-precision timers (performance.now()), and WebAssembly
threads, allowing your application to leverage multi-threaded
capabilities securely.