Your understanding is correct, but COOP/COEP are only partial solutions.
In a post-Spectre world, we want to avoid sharing a browser process with a potential attacker.
Sometimes, multiple documents from different sites can end up sharing a process in Chrome. This can happen when one has opened the other using
<a href="..." target="_blank">, or
iframes. If a website contains user-specific data, there is a chance that another site could use these new vulnerabilities to read that user data.
— Chrome Developers – Meltdown/Spectre
COOP: same-origin prevents other origins to share a browsing context group with your window through
target="_blank" links without
rel="noopener", regardless if they're in a parent or a child situation.
Cross-Origin-Opener-Policy header provides a way for a document to isolate itself from cross-origin windows opened through
window.open() or a link with
rel="noopener". As a result, any cross-origin opener of the document will have no reference to it and will not be able to interact with it.
— web.dev – Security headers quick reference
An interesting thing to note though is that COOP doesn't affect
Because COOP is defined in terms of browsing context groups, it doesn't apply to iframes; the browser ignores COOP on documents which aren't top-level, and allows iframes to access their cross-origin ancestors even if these ancestors set COOP.
With this COOP the browser can ensure that, with the exception of frames, no cross-origin documents are present in the same browsing context group / process as the current document.
— COOP and COEP explaned
On the COOP page on XS-Leaks Wiki they also highlight the fact it's a complement to framing protection:
Getting access to a website’s
window object is a common prerequisite for different XS-Leak techniques. Framing Protections can ensure that an attacker cannot use
iframes to access the
window object, but this does not stop an attacker from accessing the
window object from an opened window through
— XS Leaks Wiki – Cross-Origin-Opener-Policy
This is why we also need to set
X-Frame-Options: SAMEORIGIN (or
DENY). Even if you use
COOP: same-orgin and
CORP: same-origin, you can still be embedded in an
iframe if you don't set
X-Frame-Options. You can test this in this demo. Not setting
X-Frame-Options could leave you vulnerable to Spectre-like attacks in browsers that don't support out-of-process
As you pointed out, COEP only prevents you to include cross-origin resources that didn't explicitly opt in to it.
Cross-Origin-Opener-Policy: same-origin protects the origin from attackers
Cross-Origin-Embedder-Policy: require-corp protects victims from the origin
— InfoQ – COOP and COEP
This is why APIs that expose high precision timers are only available when COEP is enabled. Because you can perform Spectre-like attacks with those APIs, it makes sure that you can only attack resources that you have explicit permission to embed, limiting the attack surface quite a lot.
If you don't need those APIs, there's little benefit to enable COEP. If an attacker includes arbitrary resources on your site (for example through an XSS), COEP could prevent those resources to load, but in practice an attacker would likely want to include resources that they control, and where they can set
CORP: cross-origin anyways.
To sum up, here's what both the W3C and Chrome recommend to mitigate Spectre-like attacks:
- Decide when (not!) to respond to requests by examining incoming headers, paying special attention to the
Origin header on the one hand, and various
Sec-Fetch- prefixed headers on the other.
- Restrict attackers' ability to load your data as a subresource by setting a cross-origin resource policy (CORP) of
same-origin (opening up to
cross-origin only when necessary).
- Restrict attackers' ability to frame your data as a document by opt-ing into framing protections via
X-Frame-Options: SAMEORIGIN or CSP's more granular frame-ancestors directive (
frame-ancestors 'self' https://trusted.embedder, for example).
- Restrict attackers' ability to obtain a handle to your window by setting a cross-origin opener policy (COOP). In the best case, you can default to a restrictive
same-origin value, opening up to
unsafe-none only if necessary.
- Prevent MIME-type confusion attacks and increase the robustness of passive defenses like cross-origin read blocking (CORB) / opaque response blocking (ORB) by setting correct
Content-Type headers, and globally asserting
— W3C – Post-Spectre Web Development
— Chromium Blog - Mitigating Side-Channel Attacks