Cross-Origin-Resource-Policy values: same-origin vs same-site vs cross-origin (tested)
CORP lets a server say who may embed its responses (images, scripts, fonts) even without CORS. We loaded one image under each value from three kinds of pages.
1. Did the <img> load?
| Page loading the image | (no CORP) | same-origin | same-site | cross-origin |
|---|---|---|---|---|
| Same origin | Loaded | Loaded | Loaded | Loaded |
| Same site, other port | Loaded | Blocked | Loaded | Loaded |
| Other site | Loaded | Blocked | Blocked | Loaded |
A different port (or subdomain) is a different origin but the same site, so same-site is the value for assets shared between www.example.com and app.example.com. Blocked images simply fire onerror; nothing else on the page breaks.
2. Which value to use
- Private responses (user data, account images, API JSON that other sites shouldn't embed):
same-origin, orsame-siteacross your subdomains. This stops other sites from pulling them in as<img>/<script>where side channels could leak them. - Public assets meant to be embedded anywhere (a CDN, fonts, widget scripts):
cross-origin. Pages that enable cross-origin isolation (Cross-Origin-Embedder-Policy: require-corp) can only load third-party resources that send this or pass CORS. - No header behaved like
cross-originfor these loads.
# nginx
add_header Cross-Origin-Resource-Policy same-site always;
Build it with the rest of your headers in the free security headers generator. Not the same as CORS: CORS decides whether a page can read a response with fetch(), CORP whether it can embed it at all (CORS credentials, measured).
Frequently asked questions
What is the difference between CORP same-origin and same-site?
In our Chrome test, same-origin blocked an image loaded from another port on the same host; same-site allowed it and only blocked a different site.
What happens when CORP blocks a resource?
The image failed to load (onerror fired); the rest of the page was unaffected.
Do I need Cross-Origin-Resource-Policy: cross-origin?
For public assets that pages with Cross-Origin-Embedder-Policy: require-corp must load, yes. Without any header our cross-site image still loaded on a normal page.
Is CORP the same as CORS?
No. CORS controls reading a response from JavaScript; CORP controls whether another origin or site may embed it at all.
Written with AI assistance. Measured on 2026-10-01 in Chromium 153 (full build): an image server on port 8999 sent each Cross-Origin-Resource-Policy value, and pages on the same origin, on the same site with another port (localhost:8994 → localhost:8999) and on another site (localhost → 127.0.0.1) loaded it with <img>. The COEP and console-message remarks are from the spec and Chrome docs, not this test. PlainHeaders is our extension; the other methods are free.