Overview

The Content-Security-Policy header makes the browser block scripts and resources from sources the page did not allow. It is defense in depth against XSS, not a replacement for output escaping. Ship one on any site that renders user content or third-party scripts, starting with Content-Security-Policy-Report-Only to find breakage before enforcing.

Rules

  • Prefer a strict policy: a random nonce per response (or hashes for static pages) on script-src, plus object-src 'none' and base-uri 'none'. 'strict-dynamic' lets nonce-trusted scripts load others. Avoid host allowlists, 'unsafe-inline', and 'unsafe-eval'.
  • A nonce must be unpredictable and new for every response; a fixed value protects nothing, and nonce pages cannot be statically cached.
  • Send it as a header. <meta> supports only some directives (frame-ancestors is ignored).
  • frame-ancestors controls who may embed your page (replacing X-Frame-Options); frame-src controls what your page may embed.
  • Report with report-to plus a Reporting-Endpoints header. report-to became Baseline in March 2026; keep legacy report-uri alongside it for older browsers (browsers that support report-to ignore report-uri).
Content-Security-Policy: script-src 'nonce-{RANDOM}' 'strict-dynamic'; object-src 'none'; base-uri 'none'; report-to csp-endpoint