Content-Security-Policy Reference

Every CSP directive with source-list syntax, fetch vs document vs navigation types.

Interactive Content-Security-Policy reference covering fetch, document, navigation and reporting directives plus source-list keywords like nonce, self and strict-dynamic, with examples for hardening against XSS and clickjacking. Bundled offline. It runs free in your browser on Gera Tools, with nothing uploaded.

Last updated Source: Gera Tools

What is the most important CSP directive for stopping XSS?

script-src is the key directive. Restricting which scripts can run — ideally with a per-response nonce or hash plus 'strict-dynamic' and no 'unsafe-inline' — is what actually neutralises injected JavaScript. default-src provides a fallback but should be tightened per type.

A Content-Security-Policy is an allowlist the browser enforces over what a page may load and run, and it is the single strongest browser-side defence against cross-site scripting and clickjacking. The policy is a list of directives, each naming a resource type and the sources permitted for it. This reference catalogues every directive by category along with the source-list keywords you combine to build a policy.

How it works

A CSP is delivered in the Content-Security-Policy response header (or a meta tag) as semicolon-separated directives. Fetch directives (script-src, style-src, img-src, connect-src, …) govern where each resource type may load from and fall back to default-src when unset. Document directives (base-uri, sandbox) and navigation directives (form-action, frame-ancestors) constrain the document itself and where it may go — these do not fall back. Reporting directives (report-to, report-uri) send violation reports.

Each directive takes a source list of keywords and origins. The keyword 'self' means the page’s own origin, 'none' blocks everything, and a 'nonce-<value>' or 'sha256-<hash>' allows a specific inline block. 'strict-dynamic' propagates trust from a nonced script to scripts it loads, letting you drop fragile host allowlists.

A strong baseline policy

default-src 'self';
script-src 'self' 'nonce-RANDOM' 'strict-dynamic';
object-src 'none';
base-uri 'self';
frame-ancestors 'none';
form-action 'self';
upgrade-insecure-requests;
report-to csp-endpoint

This policy says: load everything from your own origin by default; allow scripts only from the same origin or carrying the correct nonce, and trust those scripts to load their own dependencies; block plugins entirely; prevent base-tag hijacking; prevent framing by any origin; restrict form submissions to the same site; and upgrade all mixed content. Violations are sent to the reporting endpoint so you can catch breakage before users do.

The nonce pattern in practice

Every server response generates a fresh cryptographic random value (the nonce) and places it in two locations: the script-src directive and the nonce attribute on every inline <script> tag the server legitimately emits. An attacker who injects a <script> block via XSS cannot know the nonce generated for that response, so the injected script is blocked even though inline scripts from the server are allowed. This model lets you eliminate 'unsafe-inline' entirely without rewriting your application to remove all inline scripts — as long as your server generates the nonce, not a build tool that bakes it in.

Common mistakes and how to avoid them

  • Using 'unsafe-inline' as a workaround: Adding 'unsafe-inline' to script-src defeats the primary purpose of CSP. If you have inline scripts you cannot move to external files, use nonces or hashes instead.
  • Omitting object-src: Flash and other plugins are controlled by object-src, not default-src fallback. Always set object-src 'none' explicitly to block plugin-based attacks.
  • Forgetting base-uri: An attacker who can inject a <base> tag can redirect all relative URLs. Set base-uri 'self' or base-uri 'none'.
  • Setting frame-ancestors only in the meta tag: The meta tag does not support frame-ancestors — it must be in the HTTP response header to prevent clickjacking.
  • Not testing with Report-Only first: Enforce too early and you break your own site. Use Content-Security-Policy-Report-Only with report-to for at least a week before switching to enforcement.

Avoid 'unsafe-inline' and 'unsafe-eval' in script-src

These keywords re-open the XSS hole CSP is meant to close. Roll out new policies with the Content-Security-Policy-Report-Only header first so you can collect violations via report-to and fix legitimate breakage before switching to enforcement.