Check a Content-Security-Policy directive by directive and see how scripts get past it
Runs in your browser. Nothing you type is sent anywhere. Checked against sources on 16 Oct 2026.A Content-Security-Policy tells the browser where scripts and other content may load from. It protects against injected scripts only if script-src avoids 'unsafe-inline', wildcards and bypassable hosts, object-src is 'none' and base-uri is restricted. A 2016 Google study found 94.7% of real policies could be bypassed; nonces with 'strict-dynamic' fix that.
Paste the policy, the whole Content-Security-Policy header line, or the <meta> tag that holds it.
Read the findings, worst first: each names the directive and what an attacker could do with it.
Check the table of directives for misspelt names and sources the browser will ignore.
Fix the policy, or start from the strict template, and paste it again until only notes remain.
A Content-Security-Policy is easy to get subtly wrong, and browsers never complain: a directive they cannot read is ignored. This tool reads the policy exactly as the CSP Level 3 specification says a browser does, then judges it against the findings of Google's 2016 study of real policies.
Findings, worst first.
| Severity | Examples |
|---|---|
| High | 'unsafe-inline' without a nonce, * or https: in script-src, object-src not 'none', 'strict-dynamic' with no nonce, a missing semicolon, self without quotes |
| Medium | 'unsafe-eval', allowlisted hosts known to serve JSONP or old AngularJS, base-uri open, plain http sources, unknown directives |
| Low | no frame-ancestors, short nonces, obsolete directives, duplicates, 'unsafe-inline' for styles |
| Note | no reporting, report-uri without report-to, sources a strict policy makes browsers ignore |
Fallback is applied. When script-src is missing, default-src is judged in its place; when both are missing, scripts may load from anywhere and the tool says so.
Paste anything. The bare policy, the whole header line, or a <meta http-equiv> tag. Policies delivered in a meta tag cannot use frame-ancestors, report-uri or sandbox, and the tool flags those. A header with several comma-separated policies is split, since each is enforced.
Every source checked. Keywords, nonces, hashes (with the right length for SHA-256, 384 or 512), schemes and hosts are checked against the grammar, and a misspelt directive gets a suggestion, such as frame-ancestor to frame-ancestors.
Strict template. One tap loads a nonce-based policy: script-src with a nonce and 'strict-dynamic', object-src 'none' and base-uri 'none'. Your server must write a new random nonce into the header and every script tag on each response.
The policy is read in your browser and never sent anywhere. To fetch the headers a live site sends, use the HTTP Headers Checker.
No. With 'unsafe-inline', any script an attacker manages to inject into the page runs, which is exactly what a Content-Security-Policy exists to stop. Use a nonce or hash for each inline script instead. Once a nonce or hash is present, modern browsers ignore 'unsafe-inline', so keeping it as a fallback for old browsers is harmless.
The 'strict-dynamic' keyword lets a script that was trusted through a nonce or hash load further scripts, while host allowlists and https: are ignored by browsers that support it. Combined with a nonce, it gives a policy that is both strict and easy to deploy. Without any nonce or hash, it blocks every script.
Plugins loaded with object or embed tags can run script outside the rules of script-src, and old Flash files on allowed hosts were a common bypass. Few sites still need plugins, so object-src 'none' removes that whole route. If object-src is missing, default-src applies, which is often not 'none'.
Popular script hosts, such as large CDNs and some Google domains, serve JSONP endpoints or old AngularJS versions. An attacker who can inject markup can load those allowed files to run their own code. Google's 2016 study found 94.7% of real allowlist policies bypassable this way; nonces with 'strict-dynamic' avoid the problem.
The browser ignores the directive and logs a console warning, but the rest of the policy still applies, so the page loses that protection silently. A typo such as frame-ancestor instead of frame-ancestors leaves the page open to clickjacking. This tool lists unknown directives and suggests the name you probably meant.
Yes, with a meta http-equiv tag in the page head, but three directives do not work there: frame-ancestors, report-uri and sandbox. Policies in a meta tag also apply only to content after the tag. Sending the policy as an HTTP response header is the reliable choice; the meta tag suits static hosting without header control.
Rates and rules change; check the source before you rely on a figure.
Still stuck? Ask about CSP Evaluator and anybody who knows can answer. No account needed.
Same job, other tools: Check IMEI Number Validity – Test a list of IMEIs for a correct Luhn check digit, one per line, and copy the results.
On the related tools: JWT Decoder – Paste a token to read its header, payload and expiry · Passphrase Generator – Three to ten random words you can actually remember.