ToolsForWeb

Saved

Tap ☆ on any tool to keep it here.

toolsforweb

Content-Security-Policy Generator

Compose a Content-Security-Policy from directives and get the header value plus Nginx, Apache and Next.js snippets.

Runs in your browser — nothing is uploaded

Loading tool…

Results are provided as is, for general information. Check anything important before relying on it. See the Terms of Use.

About this tool

A Content-Security-Policy header is a semicolon-separated list of directives, each restricting where one kind of content (scripts, styles, images, connections, frames…) can load from. Where the companion CSP Analyzer takes an existing policy apart, this tool composes one from scratch: each directive is a row with a source list — keywords like 'self', 'unsafe-inline' or 'strict-dynamic', schemes like data: and blob:, hosts, and wildcards — and the result is rendered as the raw header value plus ready-to-paste Nginx add_header, Apache Header and Next.js async headers() snippets. Delivery can be Enforce or Report-Only (with an optional report-uri), and the validator flags the settings that quietly weaken a policy while you edit. Everything runs in your browser.

When to use it

Starting a CSP for a site that doesn't have one, from a preset you can tighten incrementally.
Producing the exact add_header / Header / headers() line for whichever server or framework ships the header.
Testing a policy change in Report-Only mode before it starts blocking real traffic.
Checking how 'unsafe-inline' or a missing default-src weakens a draft before you commit to it.

Questions

What is a Content-Security-Policy?

A response header that tells the browser what the page is allowed to load: which origins may serve scripts, styles, images, fonts, network connections, frames and so on. Anything outside the allowlist is blocked (and reported, if you ask). Its headline value is XSS mitigation — even if attacker markup slips into your HTML, a policy without 'unsafe-inline' stops it executing — but it also constrains data exfiltration, framing and mixed content.

What does default-src actually do, and why does every preset start with it?

default-src is the fallback for the fetch directives you haven't set: script-src, style-src, img-src, connect-src, font-src and more all inherit from it when they have no row of their own. Starting from default-src 'self' gives you a strict baseline in one line; you then add specific directives only where the app genuinely needs more (a CDN for images, an API for connect-src). A policy without default-src is a blocklist shape — anything you forgot to restrict stays wide open.

How bad is 'unsafe-inline', really?

For script-src it defeats the core XSS protection: inline <script> tags and event-handler attributes execute exactly as they would with no CSP at all. For style-src the stakes are lower (inline styles can't execute code), which is why many real policies allow inline styles but never inline scripts. The long-term fix for scripts is a nonce or hash allowlist; if you must ship 'unsafe-inline', the tool keeps it visible in red so the weakening is a conscious decision, not a copy-paste artifact.

What does Report-Only mode change?

The header name becomes Content-Security-Policy-Report-Only: the browser evaluates your policy and logs (or POSTs, via the optional report-uri) everything it would block, but blocks nothing. This is how you ship a policy safely — run Report-Only for a few days, fix every violation that turns up in the console or your endpoint, then flip to Enforce. The generated snippets carry the right header name automatically for whichever mode is selected.

How do I test the policy once it's live?

Open the site with devtools open and browse the flows you care about — every blocked load prints a console error naming the directive and the source that was denied, so the fix is usually a one-row addition (or a report-uri entry). For automation, a browser with a --report-only CSP flag or a headless run against a Report-Only deployment surfaces the same violations. Expect a few rounds of observe-adjust-deploy before an Enforce flip; that loop is normal and far cheaper than breaking production scripts.

Why does the tool warn when I add the same directive twice?

Browsers honor only the first occurrence of a directive name in a single policy and silently ignore later ones — CSP has no directive-level merging. The duplicate row's sources therefore do nothing, which makes the policy look more permissive than it is while you debug why an origin is still blocked. Merge every source into one row; the generator keeps the first occurrence in its output to match real browser behavior.

Related tools