# Cross-Origin-Resource-Policy on static assets

- **Pattern:** `ab-002432` (`security-headers-ii.cross-origin-isolation.corp-on-assets`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-002432
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-002432)

## Why it matters

Without `Cross-Origin-Resource-Policy` on static assets, any origin can load your images, fonts, scripts, and other static files — including embedding them in pages that time their load to probe for authenticated-user-specific content. This Spectre-adjacent technique uses resource load timing differences to infer which assets a logged-in user has cached. CWE-1021 applies to unauthorized cross-origin resource embedding. OWASP A05 flags absent CORP headers as a misconfiguration gap in the cross-origin isolation stack — COEP without CORP on assets creates an isolation inconsistency.

## Severity rationale

Medium because CORP on assets is a prerequisite for `COEP: require-corp` to function correctly, and its absence leaves cross-origin resource embedding unrestricted regardless of other isolation headers.

## Remediation

Configure CORP headers on static asset routes in `next.config.js`. For private assets, use `same-origin`; for CDN-shared public assets, use `cross-origin`.

```js
// next.config.js
headers: [{
  source: '/static/(.*)',
  headers: [{
    key: 'Cross-Origin-Resource-Policy',
    value: 'same-origin'
  }]
}]
```

For the `public/` directory in Next.js, you may also need to configure CORP at the Vercel edge level via `vercel.json` headers rules, since Next.js static file serving bypasses `next.config.js` middleware for some asset paths.

## Detection

- **ID:** `corp-on-assets`
- **Severity:** `medium`
- **What to look for:** Check whether static asset responses include a `Cross-Origin-Resource-Policy` (CORP) header. CORP declares whether a resource can be loaded by other origins. Count all static asset route configurations (e.g., `public/` directory config, CDN config, static file middleware). For each, check if CORP is set. Values: `same-origin` (most restrictive), `same-site`, or `cross-origin` (for intentionally shared resources like CDN assets).
- **Pass criteria:** Static asset responses are configured with CORP headers. Report: "X of Y static asset configurations set CORP." Pass if at least 1 static asset configuration includes CORP.
- **Fail criteria:** No CORP header configured on any static asset response.
- **Skip (N/A) when:** No static assets served directly (all assets served through a CDN or build pipeline that strips custom headers).
- **Detail on fail:** `"No Cross-Origin-Resource-Policy header on static asset responses — assets can be loaded by any origin"` or `"0 of 2 static asset configurations set CORP"`
- **Remediation:** CORP controls which origins can load your resources, complementing COEP for full cross-origin isolation:

  ```js
  // next.config.js — for same-origin assets
  {
    source: '/static/(.*)',
    headers: [{
      key: 'Cross-Origin-Resource-Policy',
      value: 'same-origin'
    }]
  }
  ```

  Use `same-origin` for private assets. Use `cross-origin` for assets intentionally shared via CDN. Use `same-site` as a middle ground.

## External references

- cwe CWE-1021
- owasp A05

Taxons: access-control

HTML version: https://auditbuffet.com/patterns/ab-002432
