Why Content-Security-Policy is non-negotiable
Cross-site scripting remains the most common class of web vulnerability, and Content-Security-Policy is the single most effective defense your server can deploy. A well-crafted CSP tells the browser exactly which sources of scripts, styles, images, and other resources are permitted — anything else gets blocked before it executes. Even if an attacker injects a malicious script tag into your page, the browser refuses to load it because the source is not in your allowlist. That is why CSP is now a required check in most security audits and compliance frameworks.
The difficulty is that CSP syntax is dense and error-prone. A misplaced single quote, a forgotten directive, or an overly permissive `unsafe-inline` keyword can undermine the entire policy. This builder gives you a clean interface for adding each directive — `default-src`, `script-src`, `style-src`, `img-src`, and more — with toggle switches for `upgrade-insecure-requests` and optional `report-uri`. You copy either the raw HTTP header or the HTML meta tag version. All building happens locally in your browser.
Key CSP directives explained
Every CSP starts with `default-src`, which acts as the fallback for any directive you do not explicitly set. From there you override specific resource types: `script-src` for JavaScript, `style-src` for CSS, `img-src` for images, `font-src` for web fonts, and `connect-src` for fetch and XMLHttpRequest calls. The `upgrade-insecure-requests` flag automatically rewrites HTTP URLs to HTTPS, and `block-all-mixed-content` prevents any mixed-content loading. Understanding how `default-src` cascades to unspecified directives is the foundation of writing effective policies.
| Directive | Controls | Common sources |
|---|---|---|
| default-src | Fallback for all resource types | 'self', 'none' |
| script-src | JavaScript files and inline scripts | 'self', cdn.example.com |
| style-src | Stylesheets | 'self', 'unsafe-inline' |
| img-src | Images | 'self', data:, https: |
| connect-src | fetch, XHR, WebSocket | 'self', api.example.com |
How to build your policy
Add or edit directives starting with default-src — always begin with a restrictive baseline
Add sources for each directive: 'self' for same-origin, specific domains, or scheme keywords
Toggle upgrade-insecure-requests to enforce HTTPS across all subresources
Optionally add a report-uri endpoint to receive violation reports
Copy the HTTP header for server configuration or the meta tag for static sites
Testing your Content-Security-Policy
Deploy the header in a staging environment first — never push a new CSP directly to production. Open the browser DevTools Console and look for CSP violation messages, which tell you exactly which resource was blocked and which directive caused it. The `report-only` mode (Content-Security-Policy-Report-Only header) is invaluable here: it logs violations without actually blocking anything, letting you audit your policy safely. Once zero violations appear for normal usage, switch to the enforcing header.
Common CSP mistakes
Including `unsafe-inline` in script-src, which defeats the primary XSS protection that CSP provides
Forgetting that `default-src` does not cover frame-ancestors, base-uri, or form-action — those must be set explicitly
Using overly broad sources like `https:` which permits any HTTPS domain and weakens the policy significantly
Deploying CSP in report-only mode indefinitely without switching to enforcement
Header versus meta tag trade-offs
The HTTP header is set by your server and is the recommended approach because it supports every CSP directive including `frame-ancestors`, `report-uri`, and `report-to`. The meta tag version works for static sites or environments where you cannot modify server response headers, but it cannot set `frame-ancestors` or `report-uri`. Another limitation is that you cannot have both a header and a meta tag — the browser merges them by taking the most restrictive source for each directive, which can produce unexpected results. For most production deployments, the header is the clear choice.
Who should use a CSP Builder
Frontend developers adding security headers to web applications
Security engineers auditing and hardening existing CSP policies
Static-site owners who need a meta-tag CSP because they lack server config access
Teams migrating from permissive policies to strict nonce-based or hash-based CSP
Frequently asked questions
Q: What's the difference between the header and meta tag?
A: The HTTP header is set by your server and is recommended. The meta tag works for static sites without server config — but some directives (like frame-ancestors) only work in the header.
Q: What does 'self' mean?
A: Same-origin — only resources from the current site are allowed. Always start with default-src 'self'.
Q: Why is unsafe-inline bad?
A: It allows inline scripts and styles, which weakens CSP's XSS protection. Move inline scripts to external files where possible.
Q: Can I use nonces instead of unsafe-inline?
A: Yes — nonce-based CSP lets you allow specific inline scripts by including a cryptographic token. This is the recommended approach when inline scripts are unavoidable.
Q: How do I test a policy without breaking my site?
A: Use the Content-Security-Policy-Report-Only header. It logs violations to your report-uri endpoint without blocking any resources.
Secure your site in minutes
Build and deploy a robust Content-Security-Policy with the CSP Builder. For more security tooling, explore the HTTP Headers Decoder, the .htaccess Generator, or the nginx Config Generator.