CSP Analyzer & Builder is a free tool for Content Security Policies. Paste a policy and it goes through it directive by directive, flagging the mistakes that make a policy weaker than it looks and saying what to write instead. It shows which rule really applies to each kind of content once fallbacks are followed. Switch to the builder to write a new policy from a sensible starting point, and copy it out as a header, a meta tag, or configuration for nginx, Apache or a _headers file. Everything runs in your browser.
How to check a Content Security Policy
- Copy the policy from your site. In the browser, open DevTools, reload, choose the page’s first request in the Network tab and find
content-security-policyunder Response Headers. Or runcurl -sI https://example.com. - Paste it — the value alone, the whole header line, or a
<meta>tag all work. - Read the findings, most serious first, and the table of what actually applies.
- Choose Edit in builder to fix it, then copy the result in the format your server uses.
Why CSP mistakes are easy to miss
A Content Security Policy fails silently. A misspelt directive such as scripts-src is ignored without a warning, so whatever it was meant to restrict is not restricted. self without quotes is read as a host called “self”. A repeated directive is ignored after its first appearance. And 'unsafe-inline'in a script policy keeps every page working while quietly removing most of the protection. Nothing breaks, so none of this shows up until someone looks.
What it checks
- Scripts:
'unsafe-inline'and'unsafe-eval', wildcards and schemes such ashttps:ordata:, hosts known to serve code an attacker can reuse, and'strict-dynamic'without the nonce or hash it depends on. - Forgotten directives:
object-src, andbase-uri,form-actionandframe-ancestors, which do not fall back todefault-src. - Syntax: unquoted keywords, unknown or repeated directives,
'none'mixed with other sources, obsolete directives and short nonces. - Delivery: directives that do nothing in a
<meta>tag, and report-only policies that block nothing.
Fallbacks: what actually applies
Each fetch directive — script-src, img-src, font-src and the rest — falls back to default-src when it is missing, and a few have longer chains: workers trychild-src, then script-src, then default-src. The table under the findings follows those chains, so you can see at a glance where fonts or workers are really allowed from. A row reading “none — anything goes” means nothing in the policy covers that content at all.
Building a policy
The strict preset follows the approach browser security teams recommend: scripts are trusted by a random nonce that your server generates for every response, and 'strict-dynamic' extends that trust to the scripts they load, so there is no host list to maintain or bypass. The static-site preset suits sites that load everything from their own domain. Roll a new policy out as Report-only first, watch what it would have blocked, then enforce it. To check the rest of your security headers, use theHTTP Header Checker; to compute a hash for an inline script, use theHash Generator and base64-encode the SHA-256 digest.
Frequently asked questions
What makes a Content Security Policy strong?
Scripts trusted by nonces or hashes rather than by host lists, ideally with 'strict-dynamic'; no 'unsafe-inline' or 'unsafe-eval' for scripts; object-src 'none'; and base-uri set. That combination stops injected scripts from running even when an attacker finds a way to put markup on the page.
Why is 'unsafe-inline' so bad?
The main thing a CSP protects against is an attacker injecting a <script> into your page. 'unsafe-inline' tells the browser to run inline scripts anyway, so the injected one runs too. With a nonce or hash present, modern browsers ignore 'unsafe-inline', which is why strict policies keep it as a fallback for old browsers.
Why does it say base-uri or form-action is missing when I have default-src?
Only the fetch directives — script-src, img-src and the like — fall back to default-src. base-uri, form-action and frame-ancestors do not, so a policy without them leaves those unrestricted however strict default-src is.
Header or meta tag?
A header, where you can. A <meta> tag works for most directives, but browsers ignore frame-ancestors, sandbox and the reporting directives in it, and it only applies once the browser has read that far down the page.
How do I roll out a new policy without breaking my site?
Send it first as Content-Security-Policy-Report-Only. Browsers report what the policy would have blocked without blocking anything. Once the reports show only things you meant to block, switch to Content-Security-Policy.
Last updated