CSP Generator

Free CSP generator tool. Create custom Content Security Policy headers to prevent XSS attacks, clickjacking, and code injection.

Advertisement

CSP generator: build a Content-Security-Policy header directive by directive

A Content-Security-Policy header tells the browser which sources of script, style, images and other content it is allowed to load, and it is one of the most effective defences against cross-site scripting there is — a well-built policy stops an injected <script> from running even after it reaches the page. The catch is that it is fiddly to write by hand and unforgiving when you get it wrong: one missing source and a third-party widget goes dark. This generator lets you assemble the policy one directive at a time, add sources as keywords, URLs, nonces or hashes, and copy the result out as a raw header or as ready-made config for Nginx, Apache, Node/Express, Next.js or a Cloudflare Worker.

It runs entirely in your browser. The policy string, the nonces and the hashes are all generated on the page — nothing you type is uploaded. You can start from one of four templates and adjust, or build from an empty default-src 'self' and add only what you need.

Start from a template, then tighten

The four built-in templates are honest about the trade-off between security and how much they will break:

TemplateCentre of gravityBest for
StrictNonce-based script and style, object-src 'none', upgrades HTTPModern SPAs (React, Vue, Angular)
ModerateAllows 'unsafe-inline' for easier migration, permits Google FontsExisting sites adopting CSP gradually
Legacy CompatibleBroadest allowances, including 'unsafe-eval'Older sites and jQuery-era code, as a starting point only
Report-OnlyMonitors violations without blocking anythingThe first deployment step for any site

Loading a template drops its directives into the builder so you can see exactly what it sets and change it. The strict template is the one worth aiming at; the others exist so you can deploy something today and ratchet toward strict without a day where the site is broken.

The directives that carry most of the weight

CSP has many directives, but a handful do most of the protecting. The builder groups the full set into fetch, document, navigation, reporting and other categories; these are the ones to get right first:

  • default-src — the fallback for every fetch directive you do not set explicitly. Setting it to 'self' means "same origin only unless I say otherwise", which is the right default posture.
  • script-src — where JavaScript may come from. This is the directive that actually stops XSS, and the one worth the most care.
  • style-src — stylesheet sources. Inline styles are a common source of friction here.
  • img-src — image sources; frequently needs data: for inline images and https: for a CDN.
  • connect-src — the destinations for fetch, XMLHttpRequest, WebSocket and EventSource. Forget your API origin here and every AJAX call fails.
  • frame-ancestors — who may embed your page in an iframe. This is the modern replacement for X-Frame-Options and your anti-clickjacking control.

The generator's live validation nudges you toward the rest of a hardened baseline: it flags a missing object-src (set it to 'none' to kill plugin-based attacks), a missing base-uri (set to 'self' to prevent <base>-tag injection redirecting your relative URLs), and a missing form-action (set to 'self' so a form cannot be hijacked to post elsewhere). It also warns when no reporting is configured, and grades the policy from A+ to F as you build so you can see the effect of each change.

Why 'unsafe-inline' defeats the point, and what nonces and hashes are for

The reason CSP stops XSS is that an attacker who injects a <script> tag still cannot get it to run — the browser checks it against script-src and refuses. The moment you add 'unsafe-inline' to script-src, that guarantee evaporates: every inline script executes, including the one the attacker just injected. You have a CSP header that looks protective and blocks almost nothing. The generator marks 'unsafe-inline' and 'unsafe-eval' as unsafe in the keyword picker and raises a warning whenever they appear in script-src, for exactly this reason.

Nonces and hashes are how you keep your own inline scripts working without opening that door:

  • A nonce is a random value your server generates fresh for every response. You put 'nonce-<value>' in the header and the matching nonce="<value>" attribute on each inline script you trust. Only scripts carrying that exact value run; an injected script cannot guess it. The builder inserts a 'nonce-{RANDOM}' placeholder and can generate a real sample nonce, but the placeholder must be replaced by a server-generated value per request — a hardcoded or reused nonce is no protection at all, and the tool warns you when a placeholder is still present.
  • A hash pins a specific inline script by the SHA hash of its contents. It suits static inline blocks that never change, because there is nothing to generate per request. The generator computes SHA-256, SHA-384 or SHA-512 of the content you paste using the browser's Web Crypto API and hands you the 'sha384-…' source to drop into the directive.

The endgame for a strict policy is script-src 'nonce-<value>' 'strict-dynamic'. 'strict-dynamic' says "trust scripts that my already-trusted scripts choose to load", which lets a nonced bootstrap script pull in its dependencies without you allowlisting every CDN by hand — and it makes the policy resilient to host-based bypasses. All three keywords are in the picker.

Report-Only mode: roll out without breaking anything

The safe way to deploy a CSP is to not enforce it first. Sending the policy as a Content-Security-Policy-Report-Only header tells the browser to check every resource against the policy and report what would have been blocked — without actually blocking anything. Your site keeps working exactly as it did; you collect a list of everything the policy would break; you fix the policy until that list is empty; only then do you switch to the enforcing header. The generator has a Report-Only toggle that swaps the header name to Content-Security-Policy-Report-Only in the output, and the Report-Only template starts you there. Pair it with a report-uri or the newer report-to so the violation reports land somewhere you can read them — the validator warns if neither is set.

The practical trap: third-party scripts breaking silently

The failure that catches everyone is not a mistake in the syntax — it is forgetting a source. The moment you tighten script-src away from a wildcard, every third-party tag that is not explicitly allowed stops loading, quietly, with only a console message to show for it. The usual casualties:

  • Analytics and tag managers — Google Analytics, GTM and the like need their script origins in script-src and their collection endpoints in connect-src. Tag managers are especially awkward because they inject further scripts at runtime, which is precisely the case 'strict-dynamic' is designed for.
  • Ad tags — ad networks pull scripts, images and frames from many origins and chain to more, so they are the hardest thing to allowlist by hand.
  • Web fonts — Google Fonts serves the stylesheet from fonts.googleapis.com (needs style-src) and the font files from fonts.gstatic.com (needs font-src). Allow only one and the text falls back silently.
  • Embeds and widgets — maps, video players, chat and payment widgets typically need entries across script-src, frame-src, connect-src and img-src at once.

This is the whole argument for Report-Only mode: it surfaces every one of these before your users hit them. Deploy in report-only, exercise the real pages including the ad and analytics paths, read the reported violations, and add exactly the sources they name.

Getting the policy onto your server

A CSP is a response header, and the generator writes the config for wherever you set headers. Pick the output format and it produces the matching snippet:

FormatWhat you get
HTTP HeaderThe raw Content-Security-Policy: … line
HTML Meta TagA <meta http-equiv> tag — with warnings for the directives it cannot carry
Nginxadd_header directives
ApacheA mod_headers block
Node.js / Expressres.setHeader calls
Next.jsA headers() block for next.config.js
Cloudflare WorkersA fetch handler that rewrites the response headers

One honest limitation the tool surfaces for you: the meta-tag output cannot express every directive. frame-ancestors, report-uri and sandbox only work as real HTTP headers, so if you rely on the meta tag for clickjacking protection you have none — the generator lists exactly which directives it dropped when you choose that format. Prefer a real response header wherever you can set one.

A sensible order to build the policy in

If you are starting cold, the fastest route to a policy that both protects and does not break the site is to work in this order rather than trying to write the finished header in one go:

  • Set default-src 'self' as the backstop, so anything you forget defaults to same-origin rather than wide open.
  • Add object-src 'none', base-uri 'self', form-action 'self' and frame-ancestors 'self' — the cheap, high-value directives that rarely break anything and that the validator checks for.
  • Deploy it as Report-Only with a reporting endpoint and leave it for a real traffic cycle.
  • Read the violations and add the specific script, style, image, font and connect sources they name — nothing more.
  • Replace any 'unsafe-inline' in script-src with a nonce plus 'strict-dynamic' once you know which inline scripts are legitimately yours.
  • Only when the violation stream is quiet, switch the header name from Report-Only to enforcing.

The generator supports each of those steps directly: the templates give you the backstop, the validation catches the missing high-value directives, the Report-Only toggle handles the rollout, and the nonce and hash tools handle the inline-script migration.

Beyond CSP: the complementary headers

A second tab builds the security headers that pair with CSP but sit outside it — Permissions-Policy to switch off browser features you do not use, and the cross-origin trio Cross-Origin-Opener-Policy, Cross-Origin-Embedder-Policy and Cross-Origin-Resource-Policy that isolate your page from cross-origin tabs and control who may embed your resources. Presets range from a baseline hardening set to a full cross-origin-isolation configuration (the one that unlocks SharedArrayBuffer and high-resolution timers, at the cost of requiring every third-party resource to opt in). These generate the same per-platform config snippets as the CSP tab so you can ship the whole header set together.

What Is Content Security Policy (CSP)

Content Security Policy (CSP) is an HTTP security header that controls which resources a browser is allowed to load and execute on a web page. By defining a whitelist of trusted content sources, CSP prevents Cross-Site Scripting (XSS), data injection attacks, clickjacking, and other code injection vulnerabilities. It is one of the most effective client-side security controls available and is recommended by OWASP, NIST, and every major web security standard.

XSS remains the most common web vulnerability, affecting approximately 65% of web applications. CSP provides defense-in-depth against XSS by ensuring that even if an attacker injects malicious HTML, the browser refuses to execute unauthorized scripts, load unauthorized resources, or submit data to unauthorized endpoints.

How CSP Works

CSP is delivered as an HTTP response header that specifies directives controlling different resource types:

DirectiveControlsExample
default-srcFallback for all resource typesdefault-src 'self'
script-srcJavaScript sourcesscript-src 'self' cdn.example.com
style-srcCSS stylesheetsstyle-src 'self' 'unsafe-inline'
img-srcImage sourcesimg-src 'self' data: images.example.com
font-srcWeb fontsfont-src 'self' fonts.googleapis.com
connect-srcAJAX, WebSocket, fetch targetsconnect-src 'self' api.example.com
frame-srcIframe sourcesframe-src 'none'
object-srcPlugins (Flash, Java)object-src 'none'
base-uriAllowed tag URLsbase-uri 'self'
form-actionForm submission targetsform-action 'self'
frame-ancestorsWho can embed this pageframe-ancestors 'none'
report-uri / report-toWhere to send violation reportsreport-to csp-reports

Source values:

  • 'self' — Same origin only
  • 'none' — Block all resources of this type
  • 'unsafe-inline' — Allow inline scripts/styles (weakens CSP significantly)
  • 'unsafe-eval' — Allow eval() and similar (weakens CSP significantly)
  • 'nonce-{random}' — Allow specific inline scripts with a matching nonce
  • 'strict-dynamic' — Trust scripts loaded by already-trusted scripts
  • Domain names — Explicit origin allowlisting

Common Use Cases

  • XSS mitigation: Prevent injected scripts from executing by restricting script sources
  • Data exfiltration prevention: Restrict connect-src to prevent stolen data from being sent to attacker servers
  • Clickjacking defense: Use frame-ancestors to prevent your site from being embedded in malicious iframes
  • Mixed content prevention: Enforce HTTPS-only resources with upgrade-insecure-requests
  • Third-party script control: Explicitly allow only approved third-party scripts (analytics, chat, ads)

Best Practices

  1. Start with Content-Security-Policy-Report-Only — Deploy in report-only mode first to identify violations without breaking functionality
  2. Never use unsafe-inline for scripts — Use nonces or hashes instead; unsafe-inline defeats the purpose of CSP for XSS prevention
  3. Set object-src to none — Plugins are legacy technology and a common attack vector; block them entirely
  4. Use nonce-based CSP for modern apps — Generate a unique nonce per request and add it to allowed inline scripts: script-src 'nonce-abc123'
  5. Monitor violation reports — CSP reporting reveals both attacks and legitimate resources you forgot to whitelist

Frequently Asked Questions

What is Content Security Policy?+

Content Security Policy (CSP) is HTTP response header that controls resources browsers can load. Prevents XSS, clickjacking, code injection by whitelisting trusted sources. Example: Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com. Directives: script-src (JavaScript), style-src (CSS), img-src (images), connect-src (AJAX/WebSocket). Modern browsers support CSP Level 3. Essential defense layer for web security.

How to implement CSP on my website?+

Add CSP header to HTTP responses. Methods: web server config (Nginx, Apache), meta tag in HTML head (limited features), application framework middleware, CDN/WAF rules. Example Nginx: add_header Content-Security-Policy "default-src 'self'"; Start with Content-Security-Policy-Report-Only to test without blocking. Monitor CSP violation reports. Gradually tighten policy. Remove inline scripts/styles or use nonces. Deploy in production when violations resolved.

What is CSP nonce and how to use it?+

Nonce (number used once) is cryptographic random value allowing specific inline scripts/styles. Add nonce='random123' to CSP header and matching nonce="random123" to script/style tags. Browser compares nonces. Prevents XSS - attacker cannot guess nonce. Generate new nonce per page load using CSPRNG. Example: script-src 'nonce-4AEemGb0xJptoIGFP3Nd'. Alternative to unsafe-inline. Requires server-side rendering. More secure than hashes for dynamic content.

What are common CSP directives?+

Key directives: default-src (fallback for all), script-src (JavaScript sources), style-src (CSS), img-src (images), font-src (web fonts), connect-src (fetch/XHR/WebSocket), frame-src (iframes), media-src (video/audio), object-src (plugins), base-uri (base tag), form-action (form submissions). Values: 'self' (same origin), 'none' (block all), https: (any HTTPS), specific domains. Use default-src as baseline, override with specific directives.

How to allow inline scripts with CSP?+

Three methods: 1) Nonces - unique token per page load (most secure). 2) Hashes - SHA-256/384/512 hash of script content (for static scripts). 3) unsafe-inline (insecure, avoid). Example with hash: script-src 'sha256-abc123...'. Generate hash: echo -n "alert('hello')" | openssl dgst -sha256 -binary | openssl base64. Best practice: move inline scripts to external files, use nonces for necessary inline code. Avoid unsafe-inline - negates XSS protection.

What is CSP report-only mode?+

Content-Security-Policy-Report-Only header tests CSP without blocking resources. Browsers log violations but do not enforce policy. Use to: test new CSP before deployment, identify resources needing whitelisting, monitor for policy violations. Reports sent to report-uri or report-to endpoints. Example: Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report. Deploy report-only first, fix violations, then enforce with Content-Security-Policy header.

How to handle CSP for third-party resources?+

Whitelist trusted third-party domains explicitly. Example: script-src 'self' https://cdn.jquery.com https://www.google-analytics.com. Challenges: CDNs (use SRI hashes), ads (relaxed policies needed), social widgets (frame-src), analytics (connect-src). Solutions: host resources locally, use SRI for CDN files, frame third-party content (iframe sandbox), proxy external resources. Balance security vs functionality. Review third-party integrations quarterly. Remove unused scripts.

What is Subresource Integrity (SRI)?+

SRI validates that CDN-hosted files have not been tampered with. Add integrity attribute with cryptographic hash to script/link tags. Example: <script src="https://cdn.example.com/lib.js" integrity="sha384-..." crossorigin="anonymous">. Browser verifies hash before executing. Prevents supply chain attacks (compromised CDN). Generate hashes: openssl dgst -sha384 -binary file.js | openssl base64. Use with CSP for defense in depth. Update hashes when upgrading libraries.

This tool is provided for informational and educational purposes only. All processing happens in your browser — no data is sent to or stored on our servers. While we strive for accuracy, we make no warranties about the completeness or reliability of results.