Security Tools

CSP Generator

Build Content-Security-Policy header values.

beginner5 minRuns in your browser

Interactive workspace

Inputs stay on your device — nothing is sent to our servers unless you choose to share.

Client-side only
Live previewModerate policy · 5/6

default-src

Fallback when other fetch directives are not set.

Selected sources

'self'

default-src: 'self'

script-src

Valid sources for JavaScript — keep this strict to limit XSS.

Selected sources

'self'

script-src: 'self'

style-src

Valid sources for stylesheets and inline style blocks.

Selected sources

'self''unsafe-inline'

style-src: 'self' 'unsafe-inline'

img-src

Valid sources for images and favicons.

Selected sources

'self'data:https:

img-src: 'self' data: https:

connect-src

Valid targets for fetch, XHR, WebSocket, and EventSource.

Selected sources

'self'https:

connect-src: 'self' https:

frame-ancestors

Who may embed this page in frames — clickjacking protection.

Selected sources

'self'

frame-ancestors: 'self'

base-uri

Restricts URLs that can appear in a document's <base> element.

Selected sources

'self'

base-uri: 'self'

form-action

Valid endpoints for form submissions.

Selected sources

'self'

form-action: 'self'

CSP policy string

Directive chain only — for meta tags or server config snippets

default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'self'; base-uri 'self'; form-action 'self'

HTTP response header

Ready to paste into nginx, Apache, or CDN rules

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'self'; base-uri 'self'; form-action 'self'

HTML meta tag

Alternative delivery when you cannot set response headers

<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'self'; base-uri 'self'; form-action 'self'">

Deployment tips

  • • Start with Report-Only and monitor violations before enforcing.
  • • Use nonces (nonce-...) instead of 'unsafe-inline' for scripts.
  • • Set frame-ancestors 'none' unless you need embedding.

What is CSP?

Content Security Policy tells browsers which sources are trusted for scripts, styles, images, and more — reducing XSS and data injection impact. Generated entirely in your browser.

Test policy changes in staging. Overly strict CSP can break analytics, CDNs, and third-party widgets.

Documentation

How to use this tool, practical use cases, and technical notes.

The CSP Generator is designed to produce a deployable Content-Security-Policy header in under five minutes. Here is a complete walkthrough of every control in the tool, with guidance on making the right choices for your application.

Step 1 — Choose a Policy Preset

The tool offers four starting profiles accessible via tabs at the top of the workspace. Select the one that best matches your goal:

Preset

When to Use

Default Posture

Strict

New application; security-first; willing to configure inline script nonces

Blocks nearly everything not explicitly allowed; no unsafe-inline

Balanced

Established application with some third-party dependencies

Allows unsafe-inline for styles; restricts scripts; permits HTTPS sources for images

Report-Only

Production site where you can't afford breakage; want to observe before enforcing

Same directives but delivered via Content-Security-Policy-Report-Only; violations logged, not blocked

Legacy / Dev

Legacy codebase with inline scripts and eval; development environment

Permissive; not suitable for production

Recommended starting workflow: Begin with Report-Only using a Strict or Balanced base, deploy to production, monitor violations for 1–2 weeks, tighten the policy based on real traffic, then switch to enforcing mode.

Step 2 — Configure Each Directive

The tool exposes eight directives, each with a dropdown of pre-categorized sources and a custom source input. Work through each directive relevant to your application:

default-src

The fallback directive. Any fetch directive not explicitly set in your policy inherits from default-src. Setting it to 'self' means all unspecified resource types are restricted to same-origin by default.

Source Value

Effect

Risk Level

'self'

Same origin only

✅ Low

https:

Any HTTPS URL

⚠️ Medium

'none'

Block everything (explicit allowlist only)

✅ Lowest

*

Any URL

❌ High — defeats CSP

Best practice: Set default-src 'self' and then explicitly define each other directive. This ensures that new resource types are blocked by default rather than open.

script-src

Controls which JavaScript sources are allowed to execute. This is the most security-critical directive — XSS attacks almost always involve executing unauthorized scripts.

Source Value

Effect

Recommended?

'self'

Same-origin scripts only

✅ Yes

'nonce-{random}'

Scripts with matching nonce attribute only

✅ Best practice

'sha256-{hash}'

Scripts matching specific hash

✅ For static inline scripts

'strict-dynamic'

Trusts scripts loaded by nonce/hash-trusted scripts

✅ CSP Level 3

'unsafe-inline'

All inline <script> tags

❌ Defeats XSS protection

'unsafe-eval'

eval(), setTimeout(string), etc.

❌ Dangerous; avoid

'wasm-unsafe-eval'

WebAssembly compilation only

⚠️ Use if WASM required

CDN URLs (jsDelivr, unpkg)

Scripts from named CDNs

⚠️ Trust the CDN's security

Tool tip: The tool marks 'unsafe-inline', 'unsafe-eval', and http: sources with a ⚠️ warning badge to signal elevated risk.

style-src

Controls stylesheet sources. Less dangerous than script-src but still a vector for CSS injection attacks that can exfiltrate data or manipulate UI.

Source Value

Notes

'self'

Recommended baseline

'unsafe-inline'

Often needed for frameworks (React, Vue inline styles); use with caution

'unsafe-hashes'

Allows style attributes matching a specific hash (CSP Level 3)

https://fonts.googleapis.com

Required if using Google Fonts

img-src

Controls where images and favicons can load from. The tool defaults to 'self' data: https: — a practical default that allows inline Base64 images (used by many UI frameworks) and any HTTPS-hosted image.

Source Value

Common Need

'self'

Local images

data:

Base64 embedded images (common in frameworks, email clients)

https:

Any HTTPS image host (analytics pixels, CDN images)

blob:

Canvas-generated or file-reader images

Specific host

https://cdn.example.com for pinned CDN

connect-src

Controls targets for fetch(), XMLHttpRequest, WebSocket, and EventSource. Critical for API-heavy applications and real-time features.

Source Value

Typical Use Case

'self'

API calls to own domain

https://api.example.com

Calls to a specific external API

wss://ws.example.com

WebSocket connections

https:

Any HTTPS API endpoint (broad; acceptable if no sensitive endpoints)

https://www.google-analytics.com

Google Analytics data collection

frame-ancestors

Replaces the older X-Frame-Options header. Defines which origins are allowed to embed this page in a <frame>, <iframe>, <object>, or <embed>.

Value

Effect

Use Case

'none'

Nobody can iframe this page

✅ Strongest; use for login pages, dashboards

'self'

Only same origin can iframe

Most common

https://partner.com

Specific partner origin only

Controlled embedding

*

Anyone can iframe

❌ Enables clickjacking

Note: frame-ancestors cannot be set via <meta> tag — it only works as an HTTP response header. This tool outputs it correctly in the header format but omits it from the meta tag output.

base-uri

Restricts what URLs can appear in a <base> element. Base tag injection allows attackers to rewrite all relative URLs on the page to point to a malicious server.

Value

Recommendation

'self'

✅ Recommended — restrict to own origin

'none'

✅ If you don't use <base> elements

Omitted

❌ Falls through to default-src; explicitly set for clarity

form-action

Controls where HTML forms can submit data. Without this directive, a stored XSS that injects a <form action="https://evil.com"> can silently exfiltrate user input.

Value

Effect

'self'

Forms can only submit to the same origin

https://api.example.com

Forms submit to a specific API endpoint

'none'

No form submissions allowed (rare; API-only apps)

Step 3 — Add Custom Sources

For any directive, click "Custom source" and type a hostname, URL pattern, or scheme. The tool appends it to the selected sources list and immediately updates the live output. Valid formats include:

Format

Example

Matches

Exact host

https://cdn.example.com

That exact host on HTTPS

Host with wildcard

https://*.example.com

Any subdomain of example.com

Scheme only

https:

Any URL on HTTPS

Path-specific

https://cdn.example.com/scripts/

That path only

Step 4 — Toggle Report-Only Mode

The Report-Only header toggle switches the output between:

  • Content-Security-Policy: — enforcing mode (browsers block violations)

  • Content-Security-Policy-Report-Only: — monitoring mode (browsers log violations, do not block)

Both can be deployed simultaneously in production — Report-Only for testing a new stricter policy while keeping the enforcing policy unchanged.

Step 5 — Copy Your Output

The tool generates three output formats simultaneously. Choose based on your deployment context:

Output Format

When to Use

CSP policy string

Paste into nginx add_header, Apache Header always set, CDN header rules, or application middleware

HTTP response header

Full header line ready to paste into server config files verbatim

HTML <meta> tag

When you cannot modify HTTP headers — static site generators, CDNs without header control, email HTML

Step 6 — Apply Deployment Tips

The tool surfaces three critical reminders on every policy generation:

  1. Start with Report-Only and monitor violations before switching to enforcing mode

  2. Use nonces instead of 'unsafe-inline' for scripts — nonces prevent inline script injection even if an attacker can inject HTML

  3. Set frame-ancestors 'none' unless your application legitimately needs to be embedded in iframes