Content-Security-Policy (CSP) Header Explainer & Checker
Paste a Content-Security-Policy header or meta tag to read it in plain words, find its weak spots, test what it blocks, and hash an inline script.
Would this be allowed?
Describe something the page tries to load or run. Tooltern follows the same fallback chain as the browser (for example script-src-elem, then script-src, then default-src) and tells you which directive decides.
Hash an inline script or style
The console error quotes the hash it wanted. Paste the exact text between <script> and </script> (spaces and line breaks count) to get the source to add to your policy.
How it works
Paste the Content-Security-Policy response header from your browser's network panel or curl -I, with or without the header name, or a whole <meta http-equiv="Content-Security-Policy"> tag. Each directive is listed with its sources and what they mean. Several header lines are treated as several policies, which is what browsers do: a request has to pass every one of them.
The checker grades the policy and explains each problem. It flags what really weakens a CSP against cross-site scripting: 'unsafe-inline' without a nonce or hash, 'unsafe-eval', wildcard, https: or data: script sources, and 'strict-dynamic' with nothing to start the chain. It also catches the mistakes that silently break a policy: keywords without quotes (self is read as a host called self), missing semicolons, misspelled or duplicate directives, invalid hashes, and directives a meta tag can't use, such as frame-ancestors. And it reminds you about object-src 'none', base-uri, form-action and clickjacking protection.
Would this be allowed? takes something the page does, such as loading a script from a CDN, running an inline <script>, an onclick handler, eval(), a fetch call or being framed by another site, and applies the browser's rules: the fallback from script-src-elem to script-src to default-src, host, scheme, port and path matching, 'self', nonces, hashes and 'strict-dynamic'. It names the directive that decides and shows the console message you'd get.
Hash an inline script or style computes the 'sha256-…' and 'sha384-…' sources for the exact text between the tags, using your browser's built-in crypto. Every space and line break counts, which is the usual reason a hash that looks right still fails. For the error itself, read Refused to execute inline script, Refused to connect (connect-src), Report-Only vs Enforce and Trusted Types. Need the same grade and check in a script or CI job? Anvil's free CSP checker API returns the findings as JSON, no key needed.
Questions
What does 'unsafe-inline' do in a CSP?
It lets every inline <script>, onclick attribute and javascript: URL run, which removes most of CSP's protection against XSS. If the same directive also lists a nonce or hash, modern browsers ignore 'unsafe-inline'.
Nonce or hash: which should I use?
Use a nonce when your server renders the page, since it can add a fresh random value to each response. Use hashes for static pages whose inline scripts never change.
Why is 'self' not working?
Check the quotes. Without single quotes, self is treated as a host name. Also note 'self' doesn't cover other subdomains, and doesn't allow data: or blob: URLs.
Does default-src cover everything?
No. It is the fallback for fetch directives like script-src, img-src and connect-src, but not for base-uri, form-action, frame-ancestors or sandbox, which you have to set yourself.
Is my policy sent anywhere?
No. Parsing, checking, the simulator and hashing all run in your browser, and nothing is stored. The same checks are also available as a keyless JSON API at api.oddlathe.com/v1/csp/parse if you need them from a script.
Can I set frame-ancestors in a meta tag?
No. frame-ancestors, report-uri and sandbox are ignored when the policy comes from a <meta> tag. Send them as an HTTP header.