CSP Generator — Content Security Policy, Built with the Sharp Edges Flagged
CSP Generator
Tick the directives and sources, and this page assembles a correct
single-line Content-Security-Policy for your response header or
<meta> tag — plus the notes that matter:
which directives never fall back to default-src,
when a hash or nonce silently overrides unsafe-inline,
and what strict-dynamic switches off. A built-in
SHA-256/384/512 hash generator turns inline scripts and styles into
'sha256-…' sources. Everything runs in your
browser; nothing is uploaded.
Fetch directives — where content may come from
Unticked directives are simply absent from the policy; a tick with no
sources selected is ignored. 'none' cancels the other
boxes in its row. The extra sources box takes a comma-separated
list: host names (cdn.example.com), schemes
(https:), hashes and nonces with or without their quotes.
directive
'self'
'none'
'unsafe-inline'
'unsafe-eval'
'strict-dynamic'
data:
blob:
extra sources
Document directives — what the page itself may do
These four do not fall back to default-src: leaving
them out means "no restriction", so a complete policy sets them
explicitly.
directive
'self'
'none'
extra sources
Switches, nonce and reporting
script nonce
report-uri
report-to
Policy
Nothing built yet. Tick some sources and press Build policy, or load the OWASP baseline sample.
Hash generator for inline scripts and styles
Paste the exact content between <script> and
</script> (or the style block) — byte for byte,
no leading or trailing newline — and pick an algorithm. The
result is the 'sha256-…' source CSP 3 expects.
Hash output appears here.
Deploy as a header, not a meta tag, whenever you can.
The response header is the full CSP: frame-ancestors,
report-uri and report-to only work there,
and a header is applied before the first byte of HTML is parsed.
The meta tag is the fallback for static files with no server
configuration. Check the headers your site actually sends on the
security headers checker, and
take raw response blocks apart on the
HTTP header parser.
Self-test
Re-runs the builder against fixed states: source ordering, the
'none' mutual exclusion, the OWASP baseline string, nonce and hash
quoting, the no-fallback notes for base-uri / form-action /
frame-ancestors, unsafe-inline overridden by nonce or hash,
strict-dynamic notes, Report-Only header names, meta-tag exclusions,
the hash generator against independently computed SHA vectors, and
the negative paths. Nothing is sent anywhere.
What is a Content Security Policy?
In one sentence: a CSP is a whitelist the server sends with a
page that tells the browser exactly where scripts, styles, images
and connections may come from — so even if an attacker injects
HTML, the injected script still fails to load, because its source
is not on the list.
what the page itself may do (be embedded, submit forms to, resolve relative URLs against)
no — each must be set explicitly
Reporting and misc
report-uri, report-to, upgrade-insecure-requests
where violation reports go, and legacy-URL upgrading
no (they are not fetch directives)
The sharpest edges, in one paragraph each
'unsafe-inline' vs hashes and nonces. If a directive contains a nonce or any hash source, CSP 3 says 'unsafe-inline' is ignored — it stays there for ancient browsers only. This is why "we added a nonce and kept unsafe-inline for safety" actually means modern browsers enforce the nonce. The generator flags the combination so it is a decision, not an accident.
strict-dynamic disables your allowlist. With strict-dynamic in script-src, host sources, schemes, 'self', 'unsafe-inline' and data: are all ignored for scripts; only nonces and hashes matter, and scripts they load may load further scripts. It is the modern way to run loader scripts — but it makes the rest of the script-src list decorative.
Meta tags are second class.frame-ancestors, report-uri and report-to are ignored in <meta http-equiv>. The generator shows which parts of your policy would silently not apply.
Common mistakes
Starting with default-src * plus a long list of exceptions. Work the other way: a tight default-src 'self', then widen only the directives that need widening. Narrow policies fail loudly during testing; wide policies fail silently forever.
Shipping script-src 'unsafe-inline' 'unsafe-eval' and calling it done. That policy blocks almost nothing an XSS attack wants to do. Nonce or hash your scripts, add strict-dynamic, and keep report-only running in production to catch regressions.
Forgetting that default-src does not cover everything.base-uri, form-action, frame-ancestors and sandbox have no fallback — the most-cited gap in real-world CSP deployments.
Testing in enforce mode first. Run in Report-Only with a collector for a week, read the reports, then flip to enforcement. A policy that breaks checkout is worse than no policy.
Hashing whitespace differently. A hash covers the exact bytes of the inline block; a "helpful" build step that trims trailing newlines changes every hash. Generate hashes from what ships, not from source.
FAQ
Do I need default-src if I list every directive? No, but keeping it as a floor is good hygiene: new fetch directives in future browsers then default to your baseline instead of to "allowed".
What does upgrade-insecure-requests actually do? It tells the browser to rewrite every http:// URL the page would load — images, styles, fetches — into https:// before requesting it. It is a migration tool; the end state is pages without any http:// URL at all.
Nonce or hash? Nonce when you control the server response (a random value per response, in both the header and each script tag). Hash when the HTML is static or cached. Never a static nonce — a nonce that does not change is just unsafe-inline with extra steps.
Why is my policy delivered but violations do not arrive? Check whether you are in Report-Only (reports only), whether report-uri points at a collector that accepts POST, and whether you also set the Reporting-Endpoints / Report-To machinery that the modern report-to directive requires.
Does a CSP replace other protections? No. It is one layer: keep escaping your output, keep cookies behind HttpOnly and Secure, keep HSTS. The security headers checker on this site grades the whole set.