FreeToGenerate.com

Most CSP generators hand you a header and stop. This one answers the question that matters: given this policy, is that URL allowed?

What this policy actually does

  • style-src'unsafe-inline' allows any injected script or style to run.

Does this policy allow a URL?

Blocked

Checked against script-src

Also available in: Español · Português · Français · العربية

CSP generator and checker

Write a Content-Security-Policy, then check a real URL against it — and see which expressions in your policy do nothing at all.

What is a Content Security Policy?

A Content Security Policy is an HTTP header that tells the browser where a page is allowed to load things from. It is a list of directives — script-src, img-src, style-src and so on — each followed by the sources that directive permits. If a page tries to load something the policy does not allow, the browser refuses.

The point is damage limitation. If an attacker manages to inject markup into your page, a good policy is what stops that markup from loading their script. CSP is not a substitute for escaping output correctly; it is the layer that limits how bad the failure is when escaping goes wrong.

Writing one is easy. Knowing what you actually wrote is not, and that is the gap this page tries to close. The matching rules in CSP Level 3 are more surprising than they look, and several of them cause parts of a policy to be silently ignored — so a policy can list a dozen allowed hosts that have no effect whatsoever, and nothing anywhere tells you.

How to use it

  1. Start from a preset or paste your own policy. The strict preset is nonce-based and is what modern guidance recommends; the typical one is closer to what most sites actually ship. Edit the text freely — everything below updates as you type.
  2. Read what the policy actually does. The panel underneath lists findings: expressions that are ignored, directives that are missing, and sources that undo the protection you thought you had. Each one is a rule from the specification rather than an opinion.
  3. Then check a real URL against it. Pick the kind of resource, paste the URL you want to load and the origin your page is served from. You get a verdict, the directive that was consulted after the fallback chain, and the exact source expression that decided it.

The matching rules almost nobody knows

Scheme matching is asymmetric, and it upgrades. The specification says that http scheme-part matches https, which means script-src http://example.com also permits https://example.com — but not the other way round. Writing the insecure form quietly allows both. The same rule makes ws match wss, http and https all three, which is a wider grant than almost anyone intends.

A wildcard host does not include the domain itself. The pattern *.example.com is handled by removing the leading star and requiring the host to end with .example.com, and example.com does not end with that. So a policy allowing *.example.com blocks example.com, which is the reverse of what most people assume they wrote. It also means no host pattern ever matches an IP address, because the algorithm requires a domain.

Paths are prefix matches only when they end in a slash. Without a trailing slash the match is exact, so script-src https://cdn.example/js allows exactly that one URL and nothing beneath it. The segments are also percent-decoded before comparison, which means an encoded slash is still one segment rather than two.

And ports fall back to defaults. A source with no port matches the default port for the scheme, so https://example.com and https://example.com:443 are the same origin — which is also what 'self' has to mean.

The parts of your policy that do nothing

Two rules cause expressions to be present in a policy and have no effect at all, and neither is visible unless you know to look for it.

The first is 'strict-dynamic'. When it appears in script-src or default-src, the specification says host sources and scheme sources, along with 'unsafe-inline' and 'self', are ignored when loading script. Only nonces and hashes still count. This is deliberate and it is how the modern nonce-based approach works — but it means a policy reading script-src 'strict-dynamic' 'nonce-abc' https://cdn.example 'self' allows nothing from that CDN by its host at all. The checker lists every expression it ignored and says which rule ignored it.

The second is 'unsafe-inline' beside a nonce or a hash. In that case 'unsafe-inline' is ignored, which is the whole trick behind writing a policy that degrades gracefully in older browsers: the ones that understand nonces obey the nonce, and the ones that do not fall back to 'unsafe-inline'. Useful when deliberate, alarming when accidental — so this page distinguishes the two rather than flagging 'unsafe-inline' the same way in both cases.

There is a third gap that is about absence rather than being ignored. The directives frame-ancestors, form-action and base-uri do not fall back to default-src. A policy of default-src 'self' therefore does not restrict framing at all, does not restrict where forms submit, and leaves base-uri open so injected markup can repoint every relative URL on the page. The checker will tell you plainly that no directive applies.

Honest limits

This checks URL matching, which is the part of CSP with real rules and real surprises. It does not model everything a browser does. Inline script and style, eval, redirects, worker inheritance, sandboxing, trusted types and report handling are all outside what the checker answers, and a policy that allows a URL here can still block the resource in a browser for one of those reasons.

Nonces and hashes are recognised but not evaluated. Whether a given inline script matches a nonce depends on the markup rather than the policy, so the checker treats them as expressions that exist without claiming they let any particular URL through.

The findings are rules, not a security score. A policy can pass every check here and still be weak, because CSP cannot protect a page whose own origin serves attacker-controlled script. Nothing on this page is a substitute for encoding output correctly.

There is no CSP conformance suite and no reference matcher on npm implementing the source-expression algorithms, so the engine was checked against the specification's own worked examples plus its algorithms transcribed as assertions with their section numbers. Every asymmetric rule is tested in both directions, because a suite that only checks the permissive direction is satisfied by an implementation that allows too much — which is exactly the failure that matters here.

Why is it free?

Because it costs nothing to run. The policy is parsed and the URL checked in your browser as you type; nothing is uploaded, nothing is logged, and no server sees the policy or the URLs you paste.

No account, no sign-up, nothing held back. The matching rules come from the Content Security Policy Level 3 specification rather than from another site's summary of it, and the checks that verify them are committed alongside the page.