CSP evaluator
Evaluate a site's Content-Security-Policy, or a pasted policy: inline scripts, wildcards, bypassable allowlists, nonces that never change, plugins, base-uri, framing and syntax mistakes, with a strict policy to start from.
What it checks
- Scripts first: whether
script-src(ordefault-src) lets injected scripts run through'unsafe-inline',*,https:ordata:, or relies on an allowlist of hosts. Hosts known to serve JSONP endpoints or old AngularJS, such as public CDNs and some Google endpoints, are flagged because they let an attacker run code without breaking the policy. - Nonce-based policies: that
'strict-dynamic'has a nonce or hash to start from, that nonces are long enough, and, for a site, that the nonce changes between two requests. A nonce that stays the same, often because a CDN caches the HTML, can be read and reused. - The directives strict policies need besides scripts:
object-src 'none'against plugins,base-uriagainst injected<base>tags, andframe-ancestors(or X-Frame-Options) against clickjacking. - Mistakes that silently weaken a policy: keywords without quotes (
selfinstead of'self'), misspelt or repeated directives, a missing semicolon that turns the next directive into a host name,'none'mixed with other sources, deprecated directives, and directives a<meta>tag can't set. - Report-only policies, which block nothing, and whether violations are reported anywhere.
Enter a URL to read the policy the site sends (headers and <meta> tags), or paste a policy to check it before you deploy it.
Strict CSP in practice
Google's research found that most host allowlist policies can be bypassed, which is why its recommended "strict CSP" uses a nonce on every script tag instead: script-src 'nonce-{random}' 'strict-dynamic' https: 'unsafe-inline'; object-src 'none'; base-uri 'none'. Browsers that support nonces ignore https: and 'unsafe-inline', which only keep old browsers working.
Roll it out as Content-Security-Policy-Report-Only first, fix what the reports show (usually inline event handlers such as onclick and scripts without the nonce), then switch the header to Content-Security-Policy.
Questions
- Why is 'unsafe-inline' so bad?
- Cross-site scripting usually means an attacker gets a <script> tag or event handler onto your page. 'unsafe-inline' tells the browser to run exactly that, so the policy no longer stops the attack it exists for. With a nonce or hash in the same directive, modern browsers ignore 'unsafe-inline'.
- Is 'unsafe-inline' in style-src a problem too?
- It is much less serious. Injected CSS can leak some data or change how the page looks, but it can't run code. Most sites keep it in style-src; the checks focus on scripts.
- Should I use nonces or hashes?
- Nonces suit pages generated per request. Hashes suit static sites and pages served from a cache, where a nonce would be the same for everyone. Both work with 'strict-dynamic'.
- Does the order of directives matter?
- No, but a repeated directive does: browsers use only its first occurrence and ignore the rest. And a fetch directive missing from the policy falls back to default-src, except base-uri, form-action and frame-ancestors, which don't fall back at all.
Related tools
- HTTP headersRedirect chain, response headers and a security grade.
- Website healthEvery address, every entry point and upcoming expiries on one scorecard.
- Cookie inspectorAre a site's cookies Secure, HttpOnly and SameSite, and will browsers accept them?
- HSTS preload checkerIs the domain on the browsers' HTTPS-only list, or ready to submit?
- SSL/TLS checkerChain, expiry, protocol versions and a grade.