Cross-Origin-Resource-Policy
Speculative side-channel attacks like Spectre exploit cross-origin resource embedding to leak data. The HTTP Cross-Origin-Resource-Policy response header defends against this by signaling the browser to block no-cors cross-origin or cross-site requests for the protected resource.
Usage
Cross-Origin-Resource-Policy (CORP) is a security header defined in the Fetch specification. When a server attaches this header to a response, the browser enforces an isolation boundary on the resource. Any no-cors request from a disallowed origin or site is blocked before the response body reaches the requesting document.
CORP defends static assets (images, scripts, stylesheets)
against speculative side-channel attacks like Spectre, where
a malicious page embeds a cross-origin resource and attempts
to read its contents through timing analysis. The header
works alongside
Cross-Origin-Embedder-Policy
(COEP). A page setting require-corp in COEP requires every
loaded subresource to carry a compatible
Cross-Origin-Resource-Policy header or to be served with
CORS headers.
Values
same-origin
The same-origin value restricts the resource to requests
from the same origin. Two URLs share an origin
only when the scheme, host, and port all match. A resource on
https://www.example.re is blocked from loading by
https://api.example.re under this policy because the hosts
differ.
same-site
The same-site value allows requests from any origin within
the same registrable domain. Under this policy,
https://www.example.re and https://api.example.re
are permitted to share resources because both belong to the
same site. Requests from a different registrable domain are
blocked. Securely transported responses match only securely
transported initiators: a response served over
HTTPS is shared under same-site only when the
requesting origin's scheme is HTTPS as well.
cross-origin
The cross-origin value removes CORP restrictions entirely.
The resource is available to any requesting origin. This is
the appropriate value for public CDN assets, shared fonts,
and other resources intended for broad consumption.
Example
Locking a resource to same-origin requests only, preventing any cross-origin embedding:
Cross-Origin-Resource-Policy: same-origin
Allowing same-site subdomains to load the resource while still blocking requests from external sites:
Cross-Origin-Resource-Policy: same-site
Explicitly permitting all origins to load the resource, often used for public CDN-hosted assets:
Cross-Origin-Resource-Policy: cross-origin
CORP is a delivery veto, not an access list
The mechanism separates Cross-Origin-Resource-Policy from CORS cleanly. CORS is a read permission: the response arrives and the browser decides whether script reads the contents. CORP is a veto on delivery: a blocked response becomes a network error before reaching the requesting page at all.
The check runs only on no-cors requests, which
covers plain <img>, <script>, font, and media
loads. A resource fetched with the crossorigin
attribute or mode: "cors" bypasses CORP entirely,
and satisfies
COEP require-corp
without carrying any CORP header.
Navigations follow their own rule. The check applies to iframe navigations and never to top-level ones, so Cross-Origin-Resource-Policy on a page changes nothing about visitors following links.
Failure modes worth knowing
An invalid value fails open. Anything other than the
three exact tokens parses to nothing, and nothing
means allowed. The practical version of this trap is
duplication: an origin setting the header while a CDN
or proxy adds a second copy produces a combined value
matching no token, which silently disables CORP. With
COEP active the same
mistake inverts, since a missing policy is upgraded
to same-origin and the resource blocks instead.
The same-site value carries a scheme rule. A
response delivered over HTTPS never matches
a plain-HTTP requester, even on the same site, so
mixed-scheme setups fail under same-site while
appearing correctly configured.
Diagnosis in Chromium names the cause precisely. A
blocked request shows a reason string in the network
panel, and
CorpNotSameOriginAfterDefaultedToSameOriginByCoep
states the whole story in one identifier: the
resource carried no CORP header, and the requesting
page's COEP defaulted
the missing policy to same-origin.
The header matters most as the unblocking half of
cross-origin isolation. A page shipping
COOP same-origin and
COEP require-corp
gains SharedArrayBuffer and high-resolution timers,
and every cross-origin subresource on such a page
needs either cross-origin in this header or a CORS
fetch. CDN assets are the usual casualty, failing
with network errors until the CDN emits
Cross-Origin-Resource-Policy: cross-origin.
Chrome, Firefox, and Safari all enforce CORP, and
support has been in place across the major engines
for years.
The gap sits in
COEP
credentialless, which Safari does not support, so
sites relying on the credentialless route stay
uninsulated there.
See also
- Fetch Standard: Cross-Origin-Resource-Policy
- Cross-Origin-Embedder-Policy
- Cross-Origin-Opener-Policy
- CORS
- HTTP headers