Security, Abuse & Privacy

Content Security Policy

Definition

Content Security Policy, usually shortened to CSP, is delivered as a Content-Security-Policy header whose value is a list of directives separated by semicolons. Each directive names a resource type and the origins allowed for it: default-src sets the fallback, script-src governs JavaScript, style-src governs CSS, img-src governs images, connect-src governs fetch and WebSocket calls, and frame-ancestors decides who may put your page inside a frame. A modest policy might read default-src 'self'; script-src 'self' https://cdn.jsdelivr.net; frame-ancestors 'none'. The browser enforces it; the server only states it. There is also a Content-Security-Policy-Report-Only variant that reports violations without blocking anything, which is how most policies are tested before they go live.

Why It Matters

CSP is the second line of defence against cross-site scripting: even if a malicious script gets injected into your HTML, a policy without unsafe-inline stops the browser executing it. That same strictness is the catch for anyone publishing a generated page. A strict CSP breaks inline scripts, and inline scripts are exactly what most single-file pages rely on — a page from a chat assistant typically carries all its JavaScript and CSS inside the one HTML file, with no external files at all. Apply script-src 'self' to that page and it renders as a blank shell. The honest choice is either to keep the code inline and accept a looser policy, or split the script into its own file and tighten the header.

How It Works

The server sends the header with the response; the browser parses the directives and checks every load against them. Sources can be exact origins, the keyword 'self' for the page's own origin, 'none' to forbid everything, or a per-response nonce such as script-src 'nonce-r4nd0m', which permits only inline scripts carrying that same nonce attribute. Because a nonce must change on every response, a static host that serves the same bytes to everyone cannot generate one, so static pages that need inline code use 'unsafe-inline' or a sha256 hash of the script contents instead. Missing directives fall back to default-src, so setting default-src 'self' quietly restricts fonts, media and frames as well. Violations are reported to the URL given in report-uri or report-to, and appear in the browser console either way.

Real-World Example

A team publishes an internal metrics page as 'index.html' at ops-board.99helpers.site, all of it in one file, and adds a policy of default-src 'self' by habit. The charts vanish: the inline script is blocked and so is the Tailwind stylesheet pulled from a CDN. Loosening it to default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline' https://cdn.tailwindcss.com brings the page back, and the team keeps frame-ancestors 'none' so nobody can embed the board elsewhere.

Common Mistakes

  • Copying a strict policy from a framework tutorial onto a single-file page — the inline script it depends on is the first thing blocked
  • Putting the policy in a meta tag and expecting frame-ancestors to work — that directive is ignored unless it arrives as a real HTTP header
  • Adding a nonce to a static file — the nonce must be unique per response, and a cached static file serves the same one to everybody
  • Skipping the report-only phase, so the first sign that a directive is too tight is a broken page in front of visitors

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →