SecHead
Scansiona un sitoContattaci
Header Guide16 min read

COOP, COEP, and CORP: Modern Cross-Origin Isolation

Learn how the holy trinity of cross-origin headers protects your application against advanced CPU side-channel attacks like Spectre.

SL
Seven Labs · 21 June 2026
3,142 words

A Comprehensive Guide to COOP, COEP, and CORP: Modern Cross-Origin Isolation

When the web was first designed, nobody could have predicted that a malicious website could exploit fundamental CPU architecture to read the memory of other browser tabs. Yet, that is exactly what happened with the discovery of the Spectre vulnerability in 2018. To mitigate these devastating CPU side-channel attacks, browser vendors introduced a profound security mechanism: Cross-Origin Isolation.

At the core of Cross-Origin Isolation are three critical HTTP security headers: Cross-Origin-Opener-Policy (COOP), Cross-Origin-Embedder-Policy (COEP), and Cross-Origin-Resource-Policy (CORP). Together, this holy trinity of cross-origin headers forms an impenetrable barrier that protects your application’s memory and ensures that your sensitive data remains entirely isolated from malicious actors.

In this deep dive, brought to you by SecHead, we will explore the nuances of COOP, COEP, and CORP. We will learn how they defend against advanced vulnerabilities, why they are essential for unlocking powerful web capabilities like SharedArrayBuffer, and how to implement them effectively across various server environments.


Quick Answer: What is Cross-Origin Isolation?

Cross-Origin Isolation is a highly secure browsing context group that prevents a web page from inadvertently sharing memory or process space with cross-origin documents. It is achieved by serving a web page with two specific HTTP response headers:

  1. Cross-Origin-Opener-Policy: same-origin (COOP)
  2. Cross-Origin-Embedder-Policy: require-corp (COEP)

Once cross-origin isolation is established, the browser unlocks powerful APIs, such as SharedArrayBuffer and high-resolution timers (like performance.now()), which are otherwise restricted due to the risk of side-channel attacks like Spectre. To ensure third-party resources continue to load under COEP, they must be served with the Cross-Origin-Resource-Policy (CORP) header or proper Cross-Origin Resource Sharing (CORS) headers.


The Spectre Vulnerability: Why We Need Isolation

To understand the necessity of COOP, COEP, and CORP, we must first understand the threat model they were designed to thwart.

Modern CPUs use a technique called speculative execution to optimize performance. When a CPU encounters a conditional branch (like an if statement), it tries to predict the outcome and executes the code ahead of time. If the prediction is correct, the CPU saves time. If it is wrong, the CPU discards the speculatively executed operations and proceeds down the correct path.

However, the discarded operations still leave traces in the CPU cache. The Spectre vulnerability leverages these cache traces. A malicious script can force a speculative execution of out-of-bounds memory reads and then precisely measure memory access times to deduce the contents of that memory.

🚨 CRITICAL SECURITY WARNING 🚨
Attack Vector: Spectre (CVE-2017-5753, CVE-2017-5715)
Impact: A malicious website can exploit speculative execution to read sensitive data (passwords, session tokens, personal information) from the memory space of other websites loaded in the same browser process.

If a malicious site evil.com embeds your site bank.com in an <iframe> (or opens it in a popup), and they share the same OS-level browser process, the malicious site can potentially execute a Spectre attack to read bank.com's memory.

Browsers historically grouped different origins into the same OS process to save memory. To fundamentally defeat Spectre, browsers moved towards site isolation-putting different origins in different OS processes. But to do this effectively without breaking the web, browsers needed a way for site owners to explicitly opt-in to strict isolation and sever dangerous cross-origin relationships.

This is where the new cross-origin headers come into play.


The Holy Trinity of Isolation Headers

Let's break down the three headers that make Cross-Origin Isolation possible.

1. Cross-Origin-Opener-Policy (COOP)

The Cross-Origin-Opener-Policy (COOP) header prevents other domains from opening your site and interacting with its window object.

Historically, if evil.com used window.open('https://bank.com') to open your site in a new tab, evil.com retained a reference to your site's window object. Even though the Same-Origin Policy (SOP) prevented them from directly reading your DOM, they could still navigate your window, count the number of iframes, and, most dangerously, ensure that your site was loaded in the same browsing context group (and potentially the same process) as evil.com.

By setting COOP to same-origin, you instruct the browser: "If anyone cross-origin opens this document, put it in a completely brand new, isolated browsing context group."

COOP Directives

  • same-origin: The strictest policy. The document is strictly isolated from all cross-origin openers or openees. This is required for Cross-Origin Isolation.
  • same-origin-allow-popups: Retains references to newly opened popup windows that either don't set COOP or opt out of isolation, which is useful for OAuth popups.
  • unsafe-none: The default behavior. No isolation.
HTTP/2 200 OK
Server: nginx/1.24.0
Content-Type: text/html; charset=utf-8
Cross-Origin-Opener-Policy: same-origin

By utilizing same-origin, you severe the connection. If evil.com opens your site, evil.com's reference to the new window will simply be null, completely neutralizing their ability to interact or share process space with your application.

2. Cross-Origin-Embedder-Policy (COEP)

While COOP protects your site from being controlled by others, the Cross-Origin-Embedder-Policy (COEP) protects your site from indiscriminately embedding cross-origin resources.

If your site is in an isolated, secure state, you shouldn't be allowed to blindly load a cross-origin image or script (which could contain sensitive data) into your isolated process, because your site could then theoretically use a Spectre attack to read the embedded resource's data!

COEP dictates that your document can only load cross-origin resources (images, scripts, iframes, audio, video) if those resources explicitly grant permission to be loaded.

COEP Directives

  • require-corp: A document can only load resources from the same origin, or resources from other origins that explicitly grant permission via CORP or CORS. This is required for Cross-Origin Isolation.
  • credentialless: Cross-origin requests are sent without credentials (cookies, client certificates). If the resource responds without CORP, it's allowed, but the lack of credentials means no personalized/sensitive data is exposed.
  • unsafe-none: The default behavior. Allows fetching any cross-origin resource.
HTTP/2 200 OK
Server: nginx/1.24.0
Content-Type: text/html; charset=utf-8
Cross-Origin-Embedder-Policy: require-corp

When COEP: require-corp is active, your browser acts as a strict bouncer. If an <img> tag points to https://cdn.example.com/logo.png, the browser will inspect the response headers of that image. If the image does not have an appropriate CORP header or CORS configuration, the browser will block the image from loading, throwing a network error.

3. Cross-Origin-Resource-Policy (CORP)

The Cross-Origin-Resource-Policy (CORP) header is the mechanism by which cross-origin resources grant permission to be embedded, thus satisfying the requirements of COEP.

Think of CORP as the inverse of COEP. While COEP says "I will only embed safe things," CORP says "I allow myself to be safely embedded by others."

CORP is crucial for protecting resources from being improperly embedded by malicious sites, mitigating cross-site leaks (XS-Leaks) and Spectre-based data theft.

CORP Directives

  • same-origin: Only documents from the exact same origin can embed this resource.
  • same-site: Documents from the same site (including subdomains) can embed this resource.
  • cross-origin: Any document from any origin can embed this resource. This is required if you are hosting public assets (like a CDN) that need to be loaded by sites enforcing COEP.
HTTP/2 200 OK
Server: nginx/1.24.0
Content-Type: image/png
Cross-Origin-Resource-Policy: cross-origin

If you are running a CDN or an API that serves images or scripts to third parties, you must set Cross-Origin-Resource-Policy: cross-origin on your responses. Otherwise, any client application that implements Cross-Origin Isolation will completely break when trying to load your assets.


Achieving Cross-Origin Isolation: The SharedArrayBuffer Unlock

The ultimate goal of setting these headers is often to achieve Cross-Origin Isolation.

Why do web developers care about this state? Because it unlocks highly performant, multi-threaded web capabilities.

In Web Workers, developers can use SharedArrayBuffer to share a block of memory directly between the main thread and worker threads. This allows for incredibly fast, zero-copy data manipulation, essential for heavy computational tasks like video editing (WebAssembly/FFmpeg in the browser), 3D gaming, and complex cryptographic operations.

However, SharedArrayBuffer provides the high-resolution timing precision necessary to execute a Spectre attack. Consequently, browser vendors disabled SharedArrayBuffer completely following the Spectre disclosure.

They only re-enabled it under one condition: The page must be Cross-Origin Isolated.

When you serve a page with both COOP and COEP:

HTTP/1.1 200 OK
Content-Type: text/html
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

The browser places the page in a secure process. You can verify this isolation state via JavaScript:

if (window.crossOriginIsolated) {
    console.log("Success! We are isolated.");
    const buffer = new SharedArrayBuffer(1024);
    // Proceed with high-performance operations
} else {
    console.warn("Isolation failed. SharedArrayBuffer is disabled.");
}
URL: https://app.sechead.com/editor
🔒 app.sechead.com
---------------------------------------------------
[Console] Success! We are isolated.
[Console] WebAssembly FFmpeg module loaded successfully.

Implementation Guide: Server Configurations

Implementing these headers requires careful server configuration. Below are detailed snippets for the most common web servers and environments.

Nginx Configuration

To apply the headers globally in Nginx, add the add_header directives to your server or location block.

server {
    listen 443 ssl http2;
    server_name myapp.example.com;

    # Enable Cross-Origin Isolation
    add_header Cross-Origin-Opener-Policy "same-origin" always;
    add_header Cross-Origin-Embedder-Policy "require-corp" always;

    location / {
        try_files $uri $uri/ /index.html;
    }

    # For static assets hosted on your own domain that might be requested cross-origin
    location ~* \.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot)$ {
        add_header Cross-Origin-Resource-Policy "cross-origin" always;
        expires max;
        access_log off;
    }
}

Apache HTTP Server Configuration

For Apache, ensure the headers module is enabled (a2enmod headers), and modify your .htaccess or virtual host configuration:

<IfModule mod_headers.c>
    # Enable Cross-Origin Isolation
    Header always set Cross-Origin-Opener-Policy "same-origin"
    Header always set Cross-Origin-Embedder-Policy "require-corp"

    # Set CORP for static assets
    <FilesMatch "\.(js|css|png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)$">
        Header always set Cross-Origin-Resource-Policy "cross-origin"
    </FilesMatch>
</IfModule>

Node.js (Express) Configuration

If you are using Node.js with Express, the easiest and most robust way to set security headers is via the helmet middleware.

const express = require('express');
const helmet = require('helmet');
const app = express();

// Helmet automatically sets COOP, COEP, and CORP in its default configuration
// But we can explicitly configure them for cross-origin isolation
app.use(helmet({
  crossOriginEmbedderPolicy: { policy: "require-corp" },
  crossOriginOpenerPolicy: { policy: "same-origin" },
  crossOriginResourcePolicy: { policy: "same-origin" }
}));

// If you serve static files that need to be loaded by OTHER isolated sites
// you can override CORP for specific routes
app.use('/public-assets', (req, res, next) => {
    res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
    next();
}, express.static('public'));

app.get('/', (req, res) => {
  res.send('Secure, Isolated Web Application');
});

app.listen(3000, () => console.log('Server running on port 3000'));

Best Practices and Phased Rollouts

Enabling COEP: require-corp is incredibly destructive if not handled carefully. Because it forcefully blocks all cross-origin resources lacking a CORP header, enabling it abruptly will almost certainly break your site's images, analytics scripts, ad networks, and third-party widgets.

To mitigate this, browser vendors provided a safe rollout mechanism using Report-Only headers.

Step 1: Deploy Report-Only Mode

Instead of enforcing the policy and breaking assets, use Cross-Origin-Embedder-Policy-Report-Only and Cross-Origin-Opener-Policy-Report-Only. These headers will not block anything, but they will send violation reports to a specified endpoint whenever a resource would have been blocked.

Cross-Origin-Embedder-Policy-Report-Only: require-corp; report-to="coep-endpoint"
Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="coop-endpoint"
Report-To: {"group":"coep-endpoint","max_age":86400,"endpoints":[{"url":"https://analytics.sechead.com/reports/coep"}]}

Step 2: Analyze Violation Reports

Review the logs generated by the Report-To endpoint. You will discover all the third-party assets that are failing the CORP check.

Step 3: Fix Third-Party Assets

For every violation, you have three options:

  1. Contact the Third-Party: Ask the provider to add the Cross-Origin-Resource-Policy: cross-origin header to their assets. (Most major CDNs and providers like Google Fonts already do this).
  2. Use CORS: If the resource supports CORS, you can add the crossorigin attribute to your HTML tags (e.g., <img src="..." crossorigin="anonymous">). COEP allows resources fetched with valid CORS.
  3. Proxy the Asset: If the provider refuses to update their headers, you can proxy the asset through your own server and append the necessary CORP header yourself.

Step 4: Enforce Isolation

Once your reports show zero violations, you can safely switch from the -Report-Only headers to the standard enforced headers, fully achieving cross-origin isolation without breaking your user experience.


Debugging and Troubleshooting

When implementing COOP and COEP, the Chrome and Firefox DevTools are your best friends.

Network Tab Indicators

If COEP blocks an asset, it will appear highlighted in red in the Network tab. If you click on the blocked request, the browser will explicitly state that the request was blocked due to missing CORP or CORS headers.

[Network Panel]
Name           Status   Type      Initiator
-------------------------------------------------
logo.png       (blocked) image     (index):42
analytics.js   (blocked) script    (index):105

Error Detail: 
"To embed this resource in your document, you must set the 'crossorigin' attribute and the resource must return an appropriate Access-Control-Allow-Origin header, or the resource must return a Cross-Origin-Resource-Policy header."

Application Panel

In Chrome DevTools, open the Application tab, navigate to Frames -> top. Here, you will find an "Isolation" section that definitively tells you whether your document has successfully achieved the crossOriginIsolated state, and if not, exactly which header is preventing it.


People Also Ask (AEO)

Does COEP affect SEO?

No, Cross-Origin-Embedder-Policy does not negatively impact search engine optimization. Search engine crawlers evaluate your content independently of process isolation policies. However, if you misconfigure COEP and inadvertently block critical CSS or images from rendering, search engines may penalize the user experience, indirectly affecting SEO.

Can I use WebRTC without Cross-Origin Isolation?

Yes, standard WebRTC functionality works without Cross-Origin Isolation. However, if you are performing advanced real-time video processing requiring WebAssembly and SharedArrayBuffer before sending frames over WebRTC, you will need COOP and COEP.

What is the difference between CORS and CORP?

CORS (Cross-Origin Resource Sharing) dictates whether a cross-origin script can read the contents of a response (e.g., via fetch()). CORP (Cross-Origin Resource Policy) dictates whether a cross-origin document can simply embed or load a resource (e.g., an image in an <img> tag or a script in a <script> tag).


Frequently Asked Questions (FAQ)

1. What happens if I set COOP to same-origin but leave out COEP? Your page will be isolated from cross-origin openers, which protects you from certain attacks, but you will not achieve the strict crossOriginIsolated state required for SharedArrayBuffer.

2. I enabled COEP and all my external images broke. Why? When COEP is set to require-corp, your browser demands that all embedded cross-origin resources explicitly opt-in to being embedded. If those external images do not serve a Cross-Origin-Resource-Policy header (or valid CORS headers), the browser will forcefully block them.

3. Is Cross-Origin Isolation supported in all browsers? Yes, COOP, COEP, and CORP are supported in all modern mainstream browsers, including Chrome, Edge, Firefox, and Safari.

4. Does COEP: credentialless solve the broken image problem? Partially. credentialless will strip cookies and client certificates from cross-origin requests. If the third-party server responds, the browser will allow the resource even without a CORP header. However, this breaks any embeds that require authentication (like private iframe widgets).

5. How do I fix a blocked Google Font under COEP? Google Fonts are generally served with proper CORS headers. You must ensure you include the crossorigin attribute in your link tag: <link href="https://fonts.googleapis.com/css2?..." rel="stylesheet" crossorigin="anonymous">.

6. Can I selectively disable COOP for specific pages? Yes. COOP is an HTTP response header, meaning it is applied on a per-document basis. You can enable it for your heavy WebAssembly application route while leaving it off for your marketing pages.

7. How does OAuth work with COOP? If your site uses a popup window for OAuth (like "Sign in with Google"), setting COOP: same-origin on your main site will sever the connection to the popup, breaking the OAuth flow. To fix this, you must either use COOP: same-origin-allow-popups or transition your OAuth flow to redirects instead of popups.

8. What is the relationship between CORP and Fetch Metadata? CORP is a declarative header set by the resource provider. Fetch Metadata (like Sec-Fetch-Site) are request headers sent by the browser. A server can use Fetch Metadata to decide whether to serve a resource, while CORP tells the browser whether it's allowed to use the resource. Both defend against XS-Leaks.

9. Do I need CORP if I don't use COEP? Yes, it is still highly recommended. Setting CORP: same-site on your internal APIs and images prevents other websites from hotlinking your assets or executing cross-site leak attacks against your users.

10. Why is performance.now() restricted? performance.now() originally provided microsecond precision. This granular timing allowed attackers to precisely measure CPU cache access speeds, facilitating Spectre. Browsers artificially reduced the precision of this timer. Cross-Origin Isolation proves you are in a secure environment, allowing browsers to safely restore high-resolution timing.

11. Does COOP protect against Cross-Site Request Forgery (CSRF)? No. COOP prevents window reference abuse and process sharing. It does not stop a malicious site from submitting a hidden <form> to your server. You still need CSRF tokens or SameSite cookies for CSRF protection.

12. Can iframes be Cross-Origin Isolated? If the top-level document is Cross-Origin Isolated, any embedded iframes must also opt-in. They must be served with the Cross-Origin-Embedder-Policy header and must also be granted permission to load via the allow="cross-origin-isolated" attribute on the iframe tag.

13. What is an XS-Leak? Cross-Site Leaks (XS-Leaks) are a class of vulnerabilities where a malicious site infers information about a user's session on another site by analyzing side channels (like network timing, error events, or frame counting). COOP and CORP are primary defenses against XS-Leaks.

14. Are there performance penalties to Cross-Origin Isolation? Generally, no. In fact, by unlocking SharedArrayBuffer, it enables massive performance gains for threaded applications. However, forcing the browser to create more distinct OS processes (site isolation) does increase the overall RAM usage of the user's device.

15. How do I test my headers locally? You can test headers locally by configuring your local development server (like webpack-dev-server, Vite, or Express) to append the headers to responses. Note that localhost is treated as a secure context, making testing straightforward.


Conclusion

The transition toward Cross-Origin Isolation represents one of the most significant architectural shifts in web security history. By implementing COOP, COEP, and CORP, you are not just checking off compliance boxes; you are actively defending your users against sophisticated hardware-level vulnerabilities and participating in the creation of a fundamentally safer internet.

While the rollout requires meticulous planning to avoid breaking third-party dependencies, the reward-absolute process isolation and the unlocking of high-performance Web APIs-is well worth the engineering effort.



Continue your journey into web security with these related, deep-dive articles from the SecHead team:

SEO Metadata

  • Meta Title: COOP, COEP, and CORP Explained: Mastering Cross-Origin Isolation
  • Meta Description: A comprehensive technical guide to achieving Cross-Origin Isolation. Learn how to configure COOP, COEP, and CORP headers to defeat Spectre and unlock SharedArrayBuffer.
  • URL Slug: /blog/coop-coep-corp-explained
  • Keywords: Cross-Origin Isolation, COOP, COEP, CORP, Spectre Mitigation, SharedArrayBuffer, Web Security, SecHead, HTTP Headers, Cross-Origin-Opener-Policy

Related articles

Free tool

Check your own security headers

Instant grade, plain-language explanations, and a full remediation plan - no signup needed.

Scan your site now →