chain
CSP Checker

Nothing is fetched. The answer comes from the CSP Level 3 matching rules, applied in this tab — so it works for a policy you have not deployed yet.

// about this tool

CSP Checker Online

Updated 2026-08-04

// how to use

  1. 1 Paste your Content-Security-Policy header value (the whole thing, semicolons and all).
  2. 2 Enter the URL the console said was refused, and pick what kind of resource it is.
  3. 3 Read the verdict — it names the directive that governed it and the expression that decided.

// examples

A wildcard that does not cover the bare domain
Input
script-src *.example.com  ·  https://example.com/a.js
Output
Blocked — *.example.com needs at least one label before example.com.
A directive falling back to default-src
Input
default-src 'self'  ·  https://app.example.com/a.js
Output
Allowed — no script-src, so default-src governs, and 'self' matches.
strict-dynamic disabling the allowlist
Input
script-src 'strict-dynamic' 'nonce-abc' https://cdn.example.com
Output
Blocked — the host allowlist is ignored; only a nonce, hash or trusted-script insert works.

// common uses

Working out which source expression blocked a resource, instead of guessing Testing a policy change before you deploy it Checking whether a CDN or analytics URL will pass before adding it Understanding why a directive you did not write is governing a request

// faq

How is this different from Google's CSP Evaluator?
They answer different questions. CSP Evaluator grades a policy's strength — it flags `unsafe-inline`, over-broad wildcards and missing directives, which is what you want when hardening. This tool answers the question you have when a resource is already being refused: does this specific URL match this specific policy, and which source expression decided it.
Why doesn't my wildcard match the bare domain?
Because `*.example.com` stands for at least one label. It matches `cdn.example.com` and `a.b.example.com`, but not `example.com` itself. If you need both, list both. This is the most common misreading of a CSP source list.
I set script-src to * and a data: URL is still blocked. Why?
Because `*` is not "anything". It covers the network schemes — http, https, ws, wss and ftp — plus your page's own scheme. `data:`, `blob:` and `filesystem:` are excluded deliberately, since they are common XSS vectors, so they have to be listed by name.
Why is my allowlist being ignored?
Almost certainly `'strict-dynamic'`. When it appears in script-src, browsers ignore every host and scheme source in that directive — the allowlist is still written there, and does nothing. Scripts then load only via a matching nonce or hash, or by being inserted by an already-trusted script.
My policy has no img-src. Are images unrestricted?
No — they fall back to `default-src`. Most directives do. The exceptions matter: `frame-ancestors`, `base-uri` and `form-action` do NOT fall back, so a policy with only `default-src` leaves all three wide open.

Use this via API

Get a free API key →
curl -X POST https://thesnaptools.com/api/v1/tools/csp-checker \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"policy":"script-src *.example.com \u00b7 https://example.com/a.js"}'
Esc
↑↓ navigate open Esc close