Introduction
Cross-Site Scripting (XSS) has been on the OWASP Top 10 since the list was created. Despite years of awareness, XSS remains one of the most common web vulnerabilities. Content Security Policy (CSP) is the most effective defense against XSS because it stops the attack at the browser level, even if your code has an injection vulnerability. A CSP header tells the browser which sources are allowed to load scripts, styles, images, and other resources. This generator lets you configure CSP directives visually and outputs the policy as an HTTP header, meta tag, or raw string.
What this tool does
- Configures all major CSP directives: default-src, script-src, style-src, img-src, font-src, connect-src, media-src, frame-src, object-src, base-uri, frame-ancestors, and form-action.
- Outputs the policy as an HTTP header (for server configuration), a meta tag (for HTML), or a raw policy string.
- Toggle upgrade-insecure-requests to force HTTPS for all subresources.
- Common values are documented inline: 'self', 'none', 'unsafe-inline', 'unsafe-eval', data:, https:.
- All configuration happens client-side. No policy is transmitted anywhere.
How this tool works
The generator collects your input for each CSP directive and assembles them into a semicolon-separated policy string. Each directive follows the format directive-name source1 source2 source3. Empty directives are omitted from the output. The output format selector wraps the policy string in the appropriate container: an HTTP header line (Content-Security-Policy: ...), an HTML meta tag (), or the raw policy string. The tool does not validate your policy against the CSP specification; it only assembles the directives you configure.
How Content Security Policy works
Content Security Policy was introduced by Mozilla in Firefox 4 (2011) and standardized by the W3C. The current version is CSP Level 3, published in 2024, though most browsers implement a mix of Level 2 and Level 3 features.
How CSP prevents XSS:
Without CSP, a browser will execute any JavaScript that appears in the page, regardless of where it came from. If an attacker injects a tag via an XSS vulnerability, the browser runs it. CSP changes this by specifying a whitelist of allowed script sources. If the injected script does not match the whitelist, the browser blocks it.
Key directives:
| Directive | Controls | Example |
|---|---|---|
| default-src | Fallback for all resource types | 'self' |
| script-src | JavaScript sources | 'self' cdn.example.com |
| style-src | CSS sources | 'self' 'unsafe-inline' |
| img-src | Image sources | 'self' data: https: |
| font-src | Font files | 'self' https://fonts.googleapis.com |
| connect-src | XHR, fetch, WebSocket | 'self' https://api.example.com |
| object-src | Flash, Java, other plugins | 'none' |
| frame-ancestors | Who can embed this page | 'none' (prevents clickjacking) |
| base-uri | Allowed base tag URLs | 'self' |
| form-action | Where forms can submit | 'self' |
Source values:
- 'self': Same origin as the page (scheme, host, port must match). - 'none': No sources allowed. Blocks everything. - 'unsafe-inline': Allows inline scripts/styles. Required for many CMS platforms but weakens CSP. - 'unsafe-eval': Allows eval(), new Function(), etc. Required by some frameworks but weakens CSP. - data:: Allows data: URIs. Common for embedded images. - https:: Allows any HTTPS origin. Broad but ensures encryption.
Best practices (per Google's CSP recommendations and Mozilla's CSP guide):
1. Start with default-src 'self' and add per-type directives as needed. 2. Set object-src 'none' and base-uri 'self' unless you have a specific reason not to. 3. Set frame-ancestors 'none' to prevent clickjacking (equivalent to X-Frame-Options: DENY). 4. Avoid 'unsafe-inline' and 'unsafe-eval' in script-src. Use nonces or hashes instead. 5. Add upgrade-insecure-requests to force HTTPS for all subresources. 6. Test with Content-Security-Policy-Report-Only before enforcing.
How to use this tool
- Set default-src to 'self' as your baseline. All resource types inherit from this unless overridden.
- Configure specific directives for resource types that need different sources (script-src, style-src, img-src, etc.).
- Set object-src to 'none' and frame-ancestors to 'none' for baseline security.
- Toggle upgrade-insecure-requests if your site uses HTTPS (recommended).
- Select the output format: HTTP Header for server config, Meta Tag for HTML, or Raw for custom use.
- Copy the output and deploy it in your web server config or HTML head.
Real-world examples
Securing a static website
A developer hosts a static website on Netlify with all assets served from the same origin. They set default-src 'self', object-src 'none', base-uri 'self', and frame-ancestors 'none'. They add upgrade-insecure-requests. The generated HTTP header is: Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; upgrade-insecure-requests. They add it to their netlify.toml file.
Allowing Google Fonts and Analytics
A marketing site uses Google Fonts and Google Analytics. The developer sets default-src 'self', style-src 'self' https://fonts.googleapis.com, font-src 'self' https://fonts.gstatic.com, img-src 'self' https://www.google-analytics.com data:, connect-src 'self' https://www.google-analytics.com. This allows the font stylesheets, font files, and analytics tracking pixels while blocking everything else.
Locking down a single-page application
A React SPA loads all scripts from the same origin and makes API calls to an external backend. The developer sets script-src 'self', connect-src 'self' https://api.example.com, img-src 'self' data:, style-src 'self' 'unsafe-inline' (because styled-components injects inline styles), and frame-ancestors 'none'. They deploy the header via their nginx config and test with Chrome DevTools to verify no CSP violations appear in the console.
Comparison with similar methods
| Method | Complexity | Typical use |
|---|---|---|
| CSP (strict, no unsafe-inline) | Medium | Maximum XSS protection for modern sites |
| CSP (with unsafe-inline) | Low | Pragmatic protection for legacy sites |
| X-Frame-Options only | Low | Clickjacking prevention only, no XSS protection |
| No policy | None | Not recommended, leaves site vulnerable to XSS |
Limitations or considerations
CSP is not a silver bullet. It prevents many XSS attacks but cannot stop all of them. If your script-src includes 'unsafe-inline' or 'unsafe-eval', CSP provides minimal XSS protection. CSP does not prevent attacks that exploit server-side vulnerabilities like SQL injection or CSRF. Some third-party scripts (analytics, ads, widgets) require broad source lists that weaken CSP. The tool does not validate that your policy is syntactically correct or that it will not break your site. Always test with Content-Security-Policy-Report-Only before enforcing the policy with the actual Content-Security-Policy header.
Frequently asked questions
Should I use the HTTP header or meta tag?
The HTTP header is preferred because it applies to all resources including those loaded before the HTML is parsed. The meta tag is easier to deploy but does not protect against some attacks. Use the header if you control your server.
What does 'unsafe-inline' do?
It allows inline scripts and styles (style attributes,