Cross-Origin-Embedder-Policy
If you’ve read a few explanations about the Cross-Origin-Embedder-Policy
header (COEP) saying that it enhances security or mitigates risks or prevents some kind of attack but it still doesn’t make any sense, that’s because they’re wrong on a simple thing.
COEP does not enhance security, not for the site that sets it, nor for other sites that it uses resources from.
The thing that enhances security is the have-data-from-other-origins “xor” use-hazardous-APIs rule. And that’s because, as you may have read, with both, a page could plausibly use a side-channel attack to steal data from other origins–bad for security. This rule prevents it from happening by saying you can’t do both on the same webpage–good for security. (The actual terms used in specs are the “cross-origin isolated capability” and “APIs that require cross-origin isolation.”)
And that rule is not called COEP, nobody turns on this rule by setting COEP, and you can’t turn off this rule by setting COEP differently or omitting it. It’s just built in the browser.
COEP
Okay so what actually is COEP?
Notice how the rule says you can’t do both of two things.
You can do one of them though.
Essentially the rule divided the web into two kinds of pages: pages that may have data from other origins and pages that may use hazardous APIs.
COEP is a header you use to specify what kind of page you have. Unset COEP or COEP: unsafe-none
indicates the page would like to have data from other origins.
COEP: require-corp
indicates the page would like to use hazardous APIs.
(Currently, browsers also require the page to have a Cross-Origin-Opener-Policy
header (COOP) set to same-origin
in order to use hazardous APIs.)
The year after the rule went into place, browsers decided there should be a third kind of page that may use hazardous APIs and also may sorta have data from other origins, but those cross-origin requests are made without credentials.
COEP: credentialless
indicates a page that would like to have that.
With COEP: require-corp
, the browser blocks site A from embedding e.g. an image from site B by default because it’s assumed unsafe.
But site B can tell the browser that it is safe to share the image with site A, in which case embedding it is fine.
There’s a mechanism for site B to say so; it’s the good old cross-origin resource sharing protocol (CORS) (I just Ctrl+F’d, and the fetch standard actually doesn’t use this phrase, but MDN says that’s what CORS stands for).
In CORS, site B can set the Access-Control-Allow-Origin
header to indicate this.
However, browsers maintain a “no-CORS” mode of making a request, a mode in which the browser doesn’t honor the Access-Control-Allow-Origin header in the response.
I haven’t looked into why this mode needs to exist.
It turns out that no-CORS is the default mode the browsers use when making a request for an <img>
tag.
If you are trying to get an image to work with COEP: require-corp
and the image is served with Access-Control-Allow-Origin allowing your origin, you can do it by telling the browser to make the request for the image in CORS mode.
To do that, add a crossorigin attribute: <img src="https://siteb.example/image.png" crossorigin>
.
This mode makes the browser honor the Access-Control-Allow-Origin
response header.
CORP
For, I don’t know, completeness, there’s also a way for site B to say that it’s okay to share the image with other origins in no-CORS mode, and that’s where the Cross-Origin-Resource-Policy
header (CORP) comes in.
CORP: cross-origin
tells the browser it’s acceptable for pages to embed the image, even if they are using hazardous APIs.
Browsers still won’t let site A access the image data directly when permitted to embed the image this way.
And you better believe browsers don’t do anything with CORP: cross-origin
in CORS mode.
If–and this seems outlandish–you’re using <img src="..." crossorigin>
with an image served with CORP: cross-origin
and no Access-Control-Allow-Origin, it won’t work.
Remove the attribute to make it work: <img src="...">
.
My last post was about either Readme banner sizing or The Google Maps contributor who only uploads a photo of the drinks menu and not the food menu. Find out which.