CSP Generator
Build Content Security Policy headers with a visual directive builder
Preset
Report-Only mode
Uses Content-Security-Policy-Report-Only — logs violations without blocking. Useful for testing.
Directives
Fallback policy for fetch directives not explicitly set.
Quick-add keyword:
Controls sources for JavaScript (inline, external, eval).
Quick-add keyword:
Controls sources for CSS stylesheets and inline styles.
Quick-add keyword:
Controls sources for images and favicons.
Quick-add keyword:
Controls sources for web fonts loaded via @font-face.
Quick-add keyword:
Controls targets for fetch, XHR, WebSocket, and EventSource.
Controls sources for <frame> and <iframe> elements.
Controls sources for <audio> and <video> elements.
Controls sources for <object>, <embed>, and <applet>.
Quick-add keyword:
Restricts URLs that can be used in a document's <base> element.
Quick-add keyword:
Restricts URLs that can be used as the target of form submissions.
Specifies valid parents that may embed this page (replaces X-Frame-Options).
URI where the browser sends CSP violation reports (deprecated; prefer report-to).
Note: frame-ancestors and report-uri are not supported in meta tags.
You just added Google Analytics to your site, and now the browser console is full of CSP violations. Or worse — you shipped without a CSP at all, and a compromised third-party script is silently loading resources from a domain you’ve never heard of. Writing a CSP by hand means memorizing 15+ directives, knowing which source keywords weaken which protections ('unsafe-inline' in script-src essentially turns off XSS protection), and remembering that the <meta> tag can’t enforce frame-ancestors. One wrong directive and you either break your site or leave a security hole.
Why This Generator (Not MDN or Manual Headers)
MDN’s CSP documentation is comprehensive — and 8,000 words long. SecurityHeaders.com scans your existing headers but doesn’t help you build new ones. This tool lets you start from presets (Basic, Strict, Google Analytics, YouTube Embeds), toggle directives visually, and see the complete header string update in real time — with warnings when you enable dangerous combinations like 'unsafe-inline' in script-src. It also generates both the HTTP header and the <meta> tag version, with a note about what the meta tag can’t enforce. All processing happens in your browser; your security configuration never leaves your device.
What Is a Content Security Policy?
A Content Security Policy (CSP) is an HTTP response header that tells the browser which resources it is permitted to load for a given page. By declaring an allowlist of trusted origins for scripts, styles, images, fonts, and other resource types, CSP significantly reduces the attack surface for Cross-Site Scripting (XSS) and data injection attacks.
Without a CSP, an attacker who injects malicious content into your page can load scripts from any origin, exfiltrate user data, hijack sessions, or deface your site. With a well-crafted CSP, those injected payloads are blocked by the browser before they execute — even if the injection itself is not caught by server-side sanitization.
CSP is delivered either as an HTTP response header (Content-Security-Policy) or as an HTML <meta> element. The header is the recommended approach because it is enforced before the browser processes any page content. The meta tag is useful when you cannot control response headers (e.g., static hosting), but it cannot enforce frame-ancestors or report-uri.
How to Use This Tool
- Choose a preset — select Basic, Strict, Google Analytics, or YouTube Embeds to start with a sensible baseline.
- Toggle directives — enable or disable individual directives using the switches.
- Add sources — use the quick-add keyword buttons (
'self','none',https:, etc.) or type a custom origin and click Add. - Enable Report-Only mode — flip the toggle to generate a
Content-Security-Policy-Report-Onlyheader that logs violations without blocking resources. Ideal for testing. - Copy the output — copy the HTTP header, the header value only, or the
<meta>tag for use in your project.
All processing happens in your browser. No data is sent to any server.
Understanding CSP Directives
Fetch Directives
These control which resource origins the browser may load for each content type. Unrecognized directives fall back to default-src.
| Directive | Controls |
|---|---|
default-src | Fallback for all fetch directives not explicitly listed |
script-src | JavaScript sources — external files, inline <script>, and eval() |
style-src | CSS sources — external stylesheets and inline <style> blocks |
img-src | Image sources — <img>, CSS background-image, favicons |
font-src | Web font sources loaded via @font-face |
connect-src | Fetch API, XMLHttpRequest, WebSocket, and EventSource targets |
frame-src | Sources for <frame> and <iframe> elements |
media-src | Sources for <audio> and <video> elements |
object-src | Sources for <object>, <embed>, and <applet> elements |
Document Directives
These restrict properties of the document itself.
| Directive | Controls |
|---|---|
base-uri | URLs allowed in a <base> element — prevents base-tag hijacking |
form-action | URLs that form submissions may target |
Navigation Directives
| Directive | Controls |
|---|---|
frame-ancestors | Valid parent frames that may embed this page. 'none' is equivalent to X-Frame-Options: DENY. Cannot be set via <meta>. |
Reporting Directives
| Directive | Controls |
|---|---|
report-uri | URI where the browser POSTs JSON violation reports. Deprecated in favour of the Reporting API (report-to). Cannot be set via <meta>. |
CSP Source Expressions
Source expressions appear after a directive name and define which origins are trusted.
| Expression | Meaning |
|---|---|
'self' | Same origin as the document (scheme + host + port must match) |
'none' | Block all sources — nothing is permitted for this directive |
'unsafe-inline' | Allow inline scripts or styles (weakens XSS protection) |
'unsafe-eval' | Allow eval(), Function(), and setTimeout with string arguments |
'strict-dynamic' | Trust scripts loaded by an already-trusted nonce-bearing script |
https: | Allow any HTTPS source (scheme-only wildcard) |
data: | Allow data: URIs (e.g., inline base64 images) |
* | Allow any origin — provides minimal protection |
https://example.com | Exact origin match |
https://*.example.com | All subdomains of example.com |
Choosing the Right Preset
Basic
The Basic preset is a permissive starting point for sites that include inline styles and analytics scripts. It allows same-origin resources and 'unsafe-inline' in style-src, which is common for sites using a CSS-in-JS framework or inline critical CSS.
Content-Security-Policy:
default-src 'self';
script-src 'self';
style-src 'self' 'unsafe-inline';
img-src 'self' data:;
font-src 'self';
object-src 'none';
base-uri 'self'
Strict
The Strict preset follows security best practices: default-src 'none' blocks everything by default, and only explicitly whitelisted directives are permitted. 'unsafe-inline' is not used — styles and scripts must come from the same origin. form-action 'self' prevents form submissions to external URLs. frame-ancestors 'none' replaces X-Frame-Options: DENY.
Content-Security-Policy:
default-src 'none';
script-src 'self';
style-src 'self';
img-src 'self';
font-src 'self';
connect-src 'self';
media-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none'
Google Analytics
Extends the Basic preset with origins required for Google Analytics 4 (GA4) and Google Tag Manager. Adds https://www.googletagmanager.com to script-src, Google Analytics domains to connect-src, and the Analytics tracking pixel to img-src.
YouTube Embeds
Extends the Basic preset to allow embedding YouTube videos. Adds https://www.youtube.com and https://www.youtube-nocookie.com to frame-src, and YouTube thumbnail domains to img-src. object-src 'none' prevents old Flash embeds.
Report-Only Mode
Content-Security-Policy-Report-Only (CSPRO) behaves exactly like a regular CSP except it does not block any resources. Instead, the browser sends a violation report to your report-uri endpoint every time a resource would have been blocked.
This is invaluable for:
- Auditing existing sites — identify which resources would be blocked by a new CSP before deploying it.
- Incremental tightening — run Report-Only in parallel with your active CSP, progressively restricting sources without breaking anything.
- Testing new directives — validate a policy change in production before enforcing it.
A typical workflow:
- Deploy CSPRO with a broad policy and a
report-uriendpoint. - Collect violation reports for a few days.
- Refine the policy to cover all legitimate resource origins.
- Switch the header from
Content-Security-Policy-Report-OnlytoContent-Security-Policy.
Avoiding Common Mistakes
Forgetting object-src 'none'
Old plug-in content (Flash, Java applets) loaded via <object> or <embed> does not inherit from default-src in all browsers. Always set object-src 'none' explicitly.
Using 'unsafe-inline' in script-src
Allowing inline scripts defeats most of CSP’s XSS protection. An attacker who injects a <script> tag can execute arbitrary code. Use nonces ('nonce-RANDOM_VALUE') or hashes ('sha256-BASE64_HASH') instead.
Forgetting base-uri 'self'
Without this directive, an attacker who injects a <base> element can redirect all relative URLs on the page to an attacker-controlled domain. Always set base-uri 'self' or base-uri 'none'.
Relying on the <meta> tag for full protection
The HTML <meta http-equiv="Content-Security-Policy"> cannot enforce frame-ancestors (clickjacking protection) or report-uri (violation reporting). Use HTTP headers for a complete policy.
Using * wildcards broadly
default-src * or script-src * allows any origin and provides minimal protection. Prefer explicit origin allowlists. If you need broad access, use https: to at least restrict to HTTPS sources.
Frequently Asked Questions
What’s the difference between CSP and X-Frame-Options?
X-Frame-Options only controls whether a page can be embedded in a frame, and only takes DENY or SAMEORIGIN values. frame-ancestors in CSP is more flexible (allows specific origins), supported in modern browsers, and takes precedence over X-Frame-Options when both are present.
Can I have multiple CSP headers?
Yes. If multiple Content-Security-Policy headers are sent, the browser enforces the intersection (most restrictive combination). This is useful for gradually tightening a policy across different response layers.
Does CSP break legitimate inline styles or scripts?
Yes, if 'unsafe-inline' is not in style-src or script-src, inline styles and scripts will be blocked. For styles, the fix is to move them to external files. For scripts, use nonces (a per-request random value added to <script nonce="..."> and script-src 'nonce-...') or hashes.
Is CSP a replacement for input sanitization? No. CSP is a defence-in-depth measure. Input sanitization and output encoding are still the primary defences against XSS. CSP reduces the impact of injections that slip through — it does not prevent them.
What happens when a resource is blocked?
The browser silently blocks the resource (it is not loaded or executed), logs a warning to the developer console, and — if a report-uri is configured — sends a violation report to that endpoint. The page continues to load; only the blocked resource is affected.
Is CSP supported in all browsers? CSP Level 2 (the version this tool generates) is supported in all modern browsers including Chrome, Firefox, Safari, and Edge. Internet Explorer 11 has partial support for CSP Level 1 only.