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.
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.
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.
// 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.
ID: security-headers-ii.cross-origin-isolation.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:
// 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.