Cross-Origin-Resource-Policy Controls Resource Embedding

A server can publish an image, script, font, or other resource at a URL without intending every site on the web to embed it. Network reachability alone does not express that boundary. A browser may be able to request a resource even when the response is not exposed to JavaScript through the same-origin policy.

Cross-Origin-Resource-Policy (CORP) gives the resource server a response-side control for that case. The header tells supporting browsers which relationship between the requesting context and the resource is acceptable for relevant no-CORS requests. If the relationship violates the policy, the browser blocks use of the response body.

CORP is deliberately narrow. It is not an authentication mechanism, an application authorization rule, or a replacement for CORS. Its value comes from letting a resource owner reject embedding relationships that would otherwise be permitted by ordinary subresource loading.

The policy travels with the resource response

A response can declare one of three policy values:

Cross-Origin-Resource-Policy: same-origin
Cross-Origin-Resource-Policy: same-site
Cross-Origin-Resource-Policy: cross-origin

same-origin is the strictest of these values. The requesting origin must match the resource origin. Because an origin includes scheme, host, and port, a sibling hostname is not automatically same-origin.

same-site permits requests whose origins are considered same-site under the browser’s site calculation. This boundary is broader than same-origin, so it should be selected only when sibling origins inside that site are intended consumers.

cross-origin explicitly permits cross-origin loading under CORP. It can be useful when another browser isolation mechanism expects an explicit resource policy but the resource is intentionally public.

The header is meaningful because the decision is attached to the response being protected. A consuming page cannot loosen a resource server’s same-origin or same-site declaration merely by adding markup on its own origin.

Same-origin and same-site are different boundaries

Origin and site are related browser concepts, but they are not interchangeable. Consider a resource served from static.example.com and a page at app.example.com. Those hosts are different origins. Depending on scheme and registrable-domain rules, they can still be same-site.

A same-origin policy on the static host therefore blocks a no-CORS load from the application host even though both names belong to the same organization. A same-site policy may permit that relationship.

This distinction matters for deployments that split applications across subdomains. Selecting same-site because it appears close to same-origin can enlarge the trust boundary to sibling hosts. If a less-trusted service shares the site boundary, that service may gain an embedding relationship that a strict origin boundary would have denied.

Scheme also matters to modern site calculations. Mixed HTTP and HTTPS deployments should not assume that sharing a registrable domain always produces the intended same-site result. Testing needs to use the actual schemes and hostnames present in production.

CORP and CORS answer different questions

CORS is centered on cross-origin requests that require permission for a response to be shared with the requesting origin. A server uses headers such as Access-Control-Allow-Origin to grant that permission for CORS-enabled fetches.

CORP addresses a different path: relevant no-CORS subresource requests. Such requests can be useful to a page even when JavaScript cannot read the response bytes directly. An image can render, for example, without exposing its body to script.

That difference is important in security reviews. A response that omits Access-Control-Allow-Origin is not necessarily protected from cross-origin embedding. If embedding itself is outside the intended trust boundary, CORP can express the restriction at the resource response.

Conversely, CORP does not grant JavaScript access to a cross-origin response. Setting Cross-Origin-Resource-Policy: cross-origin does not replace a required CORS grant. The two headers participate in different browser checks.

Blocking occurs after a request may have reached the server

CORP should not be treated as a network access control. The browser can send a request and then refuse to expose or use the response body because of the policy. The server may therefore still observe traffic from a context whose browser later blocks the resource.

This property rules out using CORP as a defense for endpoints whose security depends on the request never arriving. Authentication, authorization, CSRF defenses where applicable, and server-side request validation remain necessary.

It also means that sensitive state changes do not become safe merely because their responses carry CORP. HTTP endpoints should preserve correct method semantics and enforce authorization independently of browser response filtering.

Cross-origin isolation gives CORP a second operational role

CORP is also relevant to pages using cross-origin isolation. A document configured with Cross-Origin-Embedder-Policy: require-corp places stricter conditions on cross-origin resources loaded into that document. A resource can satisfy the embedding requirement through an appropriate CORP declaration or, for applicable request types, through CORS.

This creates a deployment dependency between the document and its subresources. Enabling cross-origin embedder policy before auditing images, scripts, workers, fonts, and third-party assets can cause resources that previously loaded successfully to be blocked.

The resource policy still needs to reflect the actual trust relationship. Adding cross-origin everywhere only to silence isolation failures removes the restriction CORP could otherwise provide. Public assets and private application assets often need different policies.

Cache behavior needs the same boundary in mind

A cache can serve the same resource representation to multiple requesters. CORP is carried in the cached response, so a stable policy remains enforceable when that response is reused by the browser or an intermediary.

Problems appear when infrastructure strips, rewrites, or inconsistently injects security headers. A resource tested directly at the origin may behave differently through a CDN, reverse proxy, or object-storage gateway if the final response lacks the expected policy.

Deployment checks should inspect the response that browsers actually receive. Header configuration belongs with the resource delivery path, not only with application source code.

Policy selection should follow the intended consumer set

A useful starting point is to identify who should embed each resource class. Assets used only by one origin fit same-origin. Assets shared by trusted sibling origins may fit same-site when the site boundary matches the intended trust boundary. Resources designed for arbitrary public embedding can use cross-origin when an explicit CORP declaration is needed.

That classification is more precise than applying one header to every object in a bucket or CDN distribution. A public logo and an application-internal image can share storage infrastructure while requiring different browser policies.

CORP is strongest when its claim stays limited: the browser should reject an otherwise loadable no-CORS resource when the requester falls outside the relationship declared by the response. Server-side authorization still protects the data, CORS still governs cross-origin response sharing for CORS requests, and document isolation policies still define requirements for the embedding page. Keeping those boundaries separate makes failures easier to diagnose and avoids treating one header as a complete browser security model.