CSP Evaluator
Find the holes in a Content-Security-Policy, ranked by severity, with a fix for each.
Try before you buy.
- Free preview: every count by severity and the first findings (up to 10), with the directives of your policy and what each falls back to.
- Locked until you unlock it: download and copy.
- Unlock: Pro pass, ₹179 for 30 days or ₹79 for 1 week, a one-time payment that never renews. Unlock: Pro pass, $5.99 for 30 days or $2.99 for 1 week, a one-time payment that never renews.
Ways to unlock shows how to get the full result.
Printing this result is locked in the free preview.
Your policy
Several policies: one header per line, or separated by commas. Nothing is sent anywhere.
What the policy does in a browser of that level: older ones ignore nonces, hashes and strict-dynamic.
The directives of your policy
| Directive | Sources | Fallback |
|---|
What the evaluation found
Paste a policy to evaluate it.
Checks after Google’s open-source CSP Evaluator (opens in a new tab) (Apache-2.0), its bypass data included; checks marked “extra” are this page’s own. To build a stronger policy, use the CSP Generator.
Locked in the free preview. Opens the ways to unlock this result.
Locked in the free preview. Batch runs unlock with a pass.
Locked in the free preview. Query results unlock with a pass.
About the CSP Evaluator
A Content-Security-Policy only protects you if it actually stops injected script, and most do not: in Google’s study of 26,011 distinct policies, 94.72% could be bypassed, and 75.81% relied on script allowlists an attacker could get around, for example through an allowed host that serves JSONP endpoints or AngularJS (Weichselbaum et al., ACM CCS).
Paste your policy — the header value, the whole Content-Security-Policy: line or the <meta> tag — and this page runs the checks of Google’s open-source CSP Evaluator on it: unsafe-inline and unsafe-eval, wildcards and bare https: or data: sources, allowlisted hosts known to serve JSONP, AngularJS or Flash, missing object-src, script-src and base-uri, weak nonces, plain-http sources, misspelt directives and keywords without quotes, and the strict-CSP advice (strict-dynamic, fallbacks, Trusted Types). It reads the policy the way a CSP3 browser does — a nonce makes unsafe-inline ignored, strict-dynamic makes host allowlists ignored — and can do the same for older CSP2 and CSP1 browsers. A few checks are added on top: frame-ancestors, form-action, duplicate and retired directives, and what a <meta> or report-only delivery cannot do.
Without a pass you see a free preview: every count by severity and the first findings, with the table of your directives. The whole report, and copying or downloading it, unlock with a Pro pass.
How to use it
- Paste the policy into the box: the value, a full
Content-Security-Policy:header line (several lines for several headers) or the<meta http-equiv>tag. Or press Load example. - Read the counts and the findings, worst first. Each one names the directive and the source, explains the risk and says how to fix it.
- Use Browsers under the box to see what an older CSP2 or CSP1 browser would enforce.
- Fix the policy (the CSP Generator builds a strict one) and paste it again until nothing above Info is left. With a pass, or once this report is unlocked, copy or download it; the free preview shows its first findings.
Examples
default-src 'self'; script-src 'self' 'unsafe-inline' https://ajax.googleapis.com
High: script-src 'unsafe-inline' lets any inline script run. High: ajax.googleapis.com is known to host JSONP endpoints and AngularJS libraries, which an attacker can load to run script. Medium (extra): frame-ancestors is missing. Strict CSP: host allowlists can often be bypassed. Possibly medium: 'self' is a risk if your site serves JSONP endpoints or user uploads. Info: no Trusted Types, no form-action, no reporting.
script-src 'nonce-R4nd0mR4nd0mR4nd0m' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none'; frame-ancestors 'self'
No high, medium or syntax findings. Info: 'unsafe-inline' is ignored next to the nonce, and https: because of 'strict-dynamic': both are fallbacks for older browsers.
default-src 'self' script-src 'self'
“script-src” looks like a directive inside default-src: a semicolon is probably missing.
Common uses
- Checking a policy before you deploy it, or one a penetration test or scanner flagged.
- Finding out why a CSP with a long list of trusted hosts still lets an attacker run script.
- Moving from a host allowlist to a strict CSP with nonces or hashes and strict-dynamic.
- Reviewing the policy a framework, plugin or CDN adds to your pages.
Severities
- High — the policy can be bypassed or does not restrict scripts at all (
unsafe-inline,*,https:,data:, a host with JSONP or AngularJS, missingscript-srcorobject-src). - Syntax — the browser reads something other than you meant: an unknown directive, a missing semicolon, a keyword without quotes.
- Medium — a weakness with limits (a short nonce, plain-http sources, missing
frame-ancestors). - Possibly high / possibly medium — risky unless you are sure of a condition (that an allowed host serves no JSONP, that you need
unsafe-eval). - Strict CSP — advice for a policy that does not depend on host allowlists.
- Info — good to know: ignored sources, reporting, retired directives.
The levels and their order are those of Google’s CSP Evaluator. Checks this page adds are marked extra.
What a strict CSP looks like
The approach the study recommends allows scripts by a per-response nonce (or a hash), and lets them load what they need with 'strict-dynamic', instead of listing hosts:
script-src 'nonce-{random}' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none'
A CSP3 browser ignores the https: and 'unsafe-inline' at the end; they only keep the page working in very old browsers. Add frame-ancestors and form-action for clickjacking and form hijacking, and require-trusted-types-for 'script' once your code is ready for Trusted Types. Source: W3C Content Security Policy Level 3.
Limitations
- The page checks the policy text; it does not load your site. Whether an allowed host really serves a JSONP endpoint or a library is known only for the hosts in the evaluator’s data, so “no known bypass” is not a guarantee.
- Browsers sometimes differ from the specification in details; test the policy in your target browsers, ideally first as Content-Security-Policy-Report-Only.
- Nothing is fetched: to check a live site’s headers, use the Security Headers Checker or paste the header from your browser’s developer tools.
Privacy
On this device: nothing is sent
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
What do I get without a pass?
Without a pass, CSP Evaluator shows every count by severity and the first findings (up to 10), with the directives of your policy and what each falls back to. Until you unlock it, the result can’t be downloaded or copied. A Pro, Premium or Ultimate pass, a one-time payment that never renews, unlocks the full result. The pricing page lists the passes and their prices.
Why is a list of trusted hosts “high” severity?
Because an attacker does not need their own server: many big CDNs and APIs serve JSONP endpoints (which wrap any callback name you give in script) or old AngularJS versions (whose templates run code). If your policy allows such a host, injected markup can load script from it. The study behind the evaluator found that 14 of the 15 hosts most often allowlisted for scripts had such endpoints.
Is 'self' unsafe?
Not by itself, but it allows every script your own origin serves, including JSONP endpoints, old libraries and files users upload. That is why it is reported as “possibly medium”: check those three, or replace 'self' with nonces or hashes.
Why does it say 'unsafe-inline' is ignored?
Since CSP Level 2, a browser ignores 'unsafe-inline' in a list that also has a nonce or a hash, and with 'strict-dynamic' it also ignores hosts and https:. Strict policies keep them on purpose, for old browsers. Choose CSP1 under Browsers to see what such a browser would allow.
Can I paste a policy from a <meta> tag?
Yes, the whole tag. A <meta> policy cannot use frame-ancestors, report-uri or sandbox, and applies only to what comes after it in the page; the evaluation says so.
What does “several policies” mean?
A response may carry several Content-Security-Policy headers, or one header with policies separated by commas. A resource must then pass every enforced policy. Paste them all, one header per line, and each is checked; a missing base-uri is reported only if none of them sets it.