Cross-Origin-Resource-Policy (CORP)

Tells the browser which sites may embed this response with <img>, <script> and similar no-CORS requests.

Updated 3 November 2026

Check your site's CORP header

We send one normal request (following redirects) and grade the Cross-Origin-Resource-Policy header on the final response.

Recommended value

Cross-Origin-Resource-Policy: same-origin
Value / directiveWhat it does
same-origin Only your exact origin may load it.
same-site Any subdomain of your registrable domain may load it.
cross-origin Any site may load it. Use for public assets and CDNs.

What CORP protects

Browsers let any page embed your images, scripts and other resources with plain tags, and the user's cookies go along. Side-channel attacks such as Spectre showed that data loaded into an attacker's process can sometimes be read. CORP lets a response say "do not load me into other sites at all".

Set same-origin (or same-site if your subdomains share resources) on responses that carry user-specific data: authenticated API responses, private file downloads, user avatars behind auth.

CORP vs CORS

They are opposites. CORS (Access-Control-Allow-Origin) grants other sites permission to read a response from JavaScript. CORP restricts other sites from embedding it at all. An API meant for other origins uses CORS; a private resource uses CORP.

Public assets on a CDN that are embedded by other sites, or by pages using COEP: require-corp, should send Cross-Origin-Resource-Policy: cross-origin.

How to set Cross-Origin-Resource-Policy

nginx

# inside your server { } block
add_header Cross-Origin-Resource-Policy "same-origin" always;

Apache

# .htaccess or virtual host (needs mod_headers)
Header always set Cross-Origin-Resource-Policy "same-origin"

Laravel middleware

// app/Http/Middleware/SecurityHeaders.php
public function handle(Request $request, Closure $next): Response
{
    $response = $next($request);
    $response->headers->set('Cross-Origin-Resource-Policy', 'same-origin');

    return $response;
}

// bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
    $middleware->append(\App\Http\Middleware\SecurityHeaders::class);
})

Express (Node.js)

app.use((req, res, next) => {
  res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
  next();
});

// or: app.use(require('helmet')()) for a sensible default set

Cloudflare

Rules → Transform Rules → Modify Response Header → Create rule.
Match: all incoming requests (or your hostname).
Then: Set static → Header name: Cross-Origin-Resource-Policy → Value: same-origin

In nginx, an add_header inside a location block discards every add_header inherited from the server block. Repeat your security headers there, or use an include file. The always flag also sends the header on error responses.

Common mistakes

  • Setting same-origin on a CDN or asset host that your own other domains embed.
  • Assuming CORP stops JavaScript reading a response. That is what the absence of CORS does; CORP stops embedding.

FAQ

What is Cross-Origin-Resource-Policy used for?

It stops other sites from embedding a response with tags like <img> or <script>, protecting user-specific data from side-channel leaks.

Is CORP the same as CORS?

No. CORS grants cross-origin read access; CORP restricts cross-origin embedding.

Headers are one of 30+ things attackers check

The free StackShield scan also checks for exposed .env files, debug mode, leaked tooling, weak TLS and more, from the outside, in about a minute.

Run a free scan