Same-Origin Policy, CORS, and CSP

The browser's default restriction on reading cross-origin responses, how a server relaxes it with CORS, and how CSP restricts what a page can load.

Purpose

The same-origin policy is the browser’s default: a script running on one origin (scheme + host

  • port) cannot read response data from a different origin. CORS (Cross-Origin Resource Sharing) is how a server opts specific origins into an exception. CSP (Content-Security-Policy) is a separate mechanism restricting which sources a page is allowed to load scripts, styles, and other resources from.

CORS example

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

A server at https://api.example.com sending these headers permits a page at https://app.example.com — and only that origin — to read its responses, including when the request carries credentials (cookies).

CSP example

Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted-cdn.example.com

This restricts the page to only executing scripts from its own origin and one named CDN — even if untrusted text somehow gets injected as a <script> tag (an XSS attempt), the browser refuses to execute it if its source isn’t on the allowed list.

Behavior notes

  • CORS is enforced by the browser, not the network — a request blocked by CORS typically still reaches the server; the browser simply withholds the response from the calling script because the server didn’t grant permission. A non-browser client (curl, a server-to-server request) has no same-origin policy to enforce and isn’t affected by CORS at all.
  • Access-Control-Allow-Origin: * (any origin) is only valid for requests without credentials; a credentialed request requires naming the exact origin.
  • CSP is defense-in-depth specifically against the impact of an XSS injection — it doesn’t prevent the injection itself (proper output encoding/textContent usage does that), but limits what a successful injection could actually execute.

Common mistakes

  • Assuming a CORS error means the request failed on the server — it usually means the server responded, but without the headers needed for the browser to hand that response to the page’s script.
  • Treating CSP as a replacement for XSS prevention rather than an additional layer — untrusted text still needs safe rendering (see The Browser and the DOM) regardless of CSP.

Runtime notes

All three are browser enforcement mechanisms defined by web standards (the Fetch standard for CORS, the W3C/WHATWG CSP specification) — none apply to non-browser HTTP clients.

Taught in these lessons

Related reference

Updated 2026-09-03