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 window.open
, or <a href="..." target="_blank">
, or iframe
s. 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 window.open
or target="_blank"
links without rel="noopener"
, regardless if they're in a parent or a child situation.
The 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 target="_blank"
without 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 iframe
s:
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 iframe
s to access the window
object, but this does not stop an attacker from accessing the window
object from an opened window through window.open(url)
or window.opener
references.
— 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 COEP: require-corp
, 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 iframe
s.
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 same-site
or 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 same-origin-allow-popups
or 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 X-Content-Type-Options: nosniff
.
— W3C – Post-Spectre Web Development
— Chromium Blog - Mitigating Side-Channel Attacks