CSP Generator
Build a Content-Security-Policy directive by directive, with strict and starter presets, nonce and hash support, live syntax validation and ready-to-paste server configuration.
Runs locallyEverything happens in your browser. What you paste or drop here is never uploaded, logged or stored.
Use the tool
What a Content Security Policy actually does
A Content Security Policy is a response header that tells the browser which sources a page is allowed to load and execute code from. It does not stop an injection happening. What it does is decide what an injection is able to do once it has happened - and that is the difference between a defaced paragraph and an attacker running script with the full authority of your origin.
This tool builds that header directive by directive and explains the risk attached to each value, then produces configuration for the server you actually run. It also works the other way round: paste a policy you already have and it will tell you what is wrong with it.
Everything here runs in your browser
The policy you build or paste is never sent anywhere. That matters more than it might sound: a production CSP names your internal CDNs, your analytics vendors, your payment providers and sometimes staging hostnames that were never meant to be public. It is a map of your infrastructure, and it does not belong in someone else's server log.
The four directives that have no fallback
Most fetch directives fall back to default-src when absent, so setting
default-src 'self' covers images, fonts, styles, connections and the rest. Four
important directives do not participate in that fallback, and leaving them out
means no restriction at all rather than an inherited one. This is the single most common way a
policy does less than its author believes.
-
base-uri- controls what<base href>may be set to. Without it, one injected<base>tag silently repoints every relative script URL on the page at an attacker's host. No script tag needs to be injected at all; the ones you wrote do the work. -
frame-ancestors- controls who may frame your page. This is the modern replacement forX-Frame-Options, and where both are present it takes precedence. Without it, anyone can frame you, which is what clickjacking requires. -
form-action- controls where forms may submit. Without it, injected markup can retarget your login form to another origin, along with whatever it carries. -
object-src- in practice always set this to'none'. Legacy plugin content can execute script in waysscript-srcdoes not govern, and essentially no modern site needs it.
Why 'unsafe-inline' undoes most of the policy
'unsafe-inline' in script-src permits inline script - which is exactly
what an injected <script> tag is. A policy with it still restricts which
external hosts may serve scripts, but it no longer stops the most common form of cross-site
scripting, which is the reason most sites deploy CSP in the first place.
The fix is a nonce: a fresh random value generated per response, placed on the
<script> tags you control and named in the policy. There is a detail here worth
knowing, because it saves an argument during rollout: when a nonce or hash is present, browsers
from CSP Level 2 onward ignore 'unsafe-inline' entirely. So you can
leave it in the policy as a fallback for very old browsers without weakening it for modern ones.
This tool reports that case as informational rather than as a finding.
Use CSP Nonce and Hash Generator to produce nonces and hashes correctly, and check a live site with CSP Checker.
Roll out in report-only mode first
Enforcing a policy you have not measured will break a working site, usually in a way that only
shows up for a subset of visitors. Deploy it as
Content-Security-Policy-Report-Only first. The browser then evaluates the policy,
reports what it would have blocked, and blocks nothing.
- Build the policy here and deploy it as report-only with a reporting endpoint.
- Leave it long enough to cover real traffic - a week catches weekly jobs and unusual browsers.
- Feed the reports into CSP Report Analyzer, which separates genuine blocks from browser-extension noise.
- Adjust until the only remaining reports are things you actually want blocked.
- Move the same policy to the enforcing
Content-Security-Policyheader.
Keep report-uri alongside report-to during this. report-uri
is formally deprecated, but browser support for report-to is still incomplete and you
will lose reports without it.
A note on the meta tag
A policy can be delivered in a <meta http-equiv> tag, but several directives are
ignored there - frame-ancestors, report-uri and sandbox
among them - and report-only mode does not work by meta tag at all. Use a response header wherever
you can. This tool marks the meta output with those limitations rather than pretending they do not
exist.
Frequently asked questions
Will adding a CSP break my site?
A strict one, deployed straight to enforcing mode, very likely will. That is why report-only exists and why this tool defaults to it. Deployed the way described above, the risk is small, because you will have seen everything the policy would block before it blocks anything.
Is 'strict-dynamic' better than listing hosts?
Usually, yes, for an application that loads script dynamically. It discards host allow-lists and trusts only script loaded by already-trusted script, so you stop maintaining a list of CDNs. It requires a nonce or hash to establish that initial trust - with neither, nothing loads at all, and this tool reports that combination as a high-severity finding because the symptom is a blank page.
Do I still need X-Frame-Options?
Only for very old browsers. frame-ancestors supersedes it and takes precedence
where both are present. Sending both is harmless and is still common practice.
Why does my policy get a finding for having no report-uri?
Because without reporting you cannot tell whether the policy is blocking something legitimate. It is a low-severity finding rather than a high one - the policy still works - but it matters most during rollout, which is exactly when it tends to be left out.
Is my policy stored or sent anywhere?
No. Everything on this page runs in your browser. There is no request to a server carrying your policy, and nothing is written to storage.
References
Related tools
Other Tools
Popular tools from across A2Z
Rate this tool
Was this tool useful? Your feedback helps us improve it.