/public/tools/

Content-Security-Policy inspector

Paste the value of a Content-Security-Policy response header. Each directive is parsed and explained, every source is risk-rated, and the findings list flags the gaps that actually get sites popped: an active 'unsafe-inline', a wildcard host, or a missing object-src, base-uri, or frame-ancestors.

presets

analyzing…

Directives

directivesourcesmeaning

The fallback chain

Only the fetch directives fall back to default-src when absent: script-src, style-src, img-src, connect-src, font-src, media-src, object-src, frame-src, child-src, worker-src, manifest-src and the -elem/-attr variants. So default-src 'none' closes all of them at once. The document and navigation directives never fall back: if you do not write base-uri, form-action or frame-ancestors, they are simply unset and the browser default (allow) applies, no matter what default-src says.

The three gaps that bite

object-src 'none' kills legacy plugin and <object>/<embed> vectors; without it a single injected tag can run. base-uri 'none' (or 'self') stops an injected <base> tag from rewriting every relative script URL out from under your nonce. frame-ancestors is the CSP replacement for X-Frame-Options; omit it and your page can be framed for clickjacking. None of the three inherit from default-src, so a policy that looks locked-down can still be wide open on all three.

Why unsafe-inline is sometimes ignored

When a directive contains a nonce ('nonce-...') or a hash ('sha256-...'), a CSP Level 2+ browser ignores 'unsafe-inline' in that same directive. The keyword is kept only as a fallback for ancient browsers that do not understand nonces. This tool marks such an 'unsafe-inline' as neutralized rather than dangerous. The same goes for 'strict-dynamic': when present, host-source and 'self' entries in script-src are ignored, and trust flows only through nonces and hashes to the scripts they load.

What this tool does not check

It parses a single policy string. It does not fetch your page, verify that nonces are actually unique per response, confirm that hashes match real inline blocks, or evaluate multiple stacked CSP headers (browsers enforce the intersection of all of them). A few directives are also meta-tag-ignored: frame-ancestors, report-uri, report-to and sandbox only work as a real HTTP header, never in a <meta http-equiv> tag. It notes that but cannot see how you deliver the policy.

Source keyword reference

sourcemeaning
'none'Matches nothing. Blocks the entire resource type.
'self'The page's own origin (scheme + host + port). Not subdomains.
'nonce-…'Allows one inline block carrying the matching nonce attribute. Must be unguessable and per-response.
'sha256-…'Allows an inline block whose body hashes to this value. Also sha384/sha512.
'strict-dynamic'Trust propagates from a nonced/hashed script to what it loads; host and 'self' sources are then ignored.
'unsafe-inline'Allows all inline scripts/styles and on* handlers. Defeats most XSS protection. Ignored when a nonce/hash is present.
'unsafe-eval'Allows eval(), new Function(), and string timers.
'unsafe-hashes'Allows event-handler attributes and javascript: whose body matches a listed hash. Narrower than unsafe-inline but still risky.
'wasm-unsafe-eval'Allows WebAssembly compilation without allowing JS eval().
https: / data: / blob:Scheme sources. Match any host on that scheme. data: and http: in a script context are dangerous.
*.example.comHost source. The * matches one or more leading subdomain labels, not the bare domain.
*Any host over http/https (not data:/blob:). Effectively no restriction.

Single static HTML file, no network. Your policy never leaves the browser. Source: github.com/truffle-dev/tool-csp-inspector. MIT.