CSP Header Builder & Analyzer
Build a Content-Security-Policy header visually, or paste one to check for unsafe directives
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'self'; object-src 'none'; base-uri 'self'; upgrade-insecure-requests;
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; frame-ancestors 'self'; object-src 'none'; base-uri 'self'; upgrade-insecure-requests;">
Note: frame-ancestors, report-uri, and sandbox are ignored when set via <meta> — use the HTTP header for those.
About this tool
The CSP Header Builder & Analyzer helps with both directions of Content-Security-Policy work: build a policy visually by setting allowed sources per directive (script-src, style-src, img-src, and more), or paste an existing policy to check it for common misconfigurations like 'unsafe-inline', 'unsafe-eval', and wildcard sources that undermine CSP's core protection. CSP is one of the most effective browser-level defenses against XSS, but it's also one of the most commonly misconfigured security headers — a policy with 'unsafe-inline' in script-src provides close to zero XSS protection while looking like a real security control.
When to use it
- →Building a starting CSP for a new project's security headers, directive by directive
- →Auditing an existing CSP (your own, or a security scan's report) for directives that silently undermine XSS protection
- →Generating both the HTTP header and equivalent <meta> tag versions of the same policy
- →Understanding what a specific CSP directive actually restricts before adding it to production
Tips
- ◆Set CSP via the HTTP header, not the <meta> tag, whenever possible — frame-ancestors, report-uri, and sandbox are silently ignored in the <meta> tag form.
- ◆'unsafe-inline' in script-src is the single most common CSP mistake — it defeats most of CSP's XSS protection while still looking like a real policy. Use nonces or hashes for inline scripts you can't externalize.
- ◆Start restrictive (default-src 'self') and add specific sources as you find real violations in the browser console, rather than starting permissive and trying to tighten later.
Frequently asked questions
What does Content-Security-Policy actually protect against?
CSP's primary purpose is mitigating Cross-Site Scripting (XSS) — even if an attacker manages to inject a <script> tag into your page (via a stored XSS bug, for example), a correctly configured CSP prevents that script from executing because it didn't come from an allowed source. It also restricts other risky behaviors: framing (clickjacking), form submission targets, and base URI manipulation.
Why does 'unsafe-inline' defeat the purpose of CSP?
CSP's core XSS defense works by only allowing scripts from trusted, explicitly listed sources. 'unsafe-inline' tells the browser to allow ANY inline <script> tag or inline event handler to execute — which is exactly the mechanism most XSS attacks use to run injected code. A policy with 'unsafe-inline' in script-src is only marginally better than no CSP at all for XSS purposes.
What should I use instead of 'unsafe-inline' for scripts I can't move to external files?
Use a nonce (a random, per-request token added to both the CSP header and the script tag: <script nonce="random123">) or a hash of the exact script content (CSP allows 'sha256-<hash>' as a source). Both let specific inline scripts run without opening the door to arbitrary injected scripts, since an attacker can't guess the nonce or produce content matching the hash.
Do I need report-uri or report-to in my CSP?
Not strictly required, but strongly recommended for production — it tells the browser to send a report whenever the policy blocks something, which is how you discover legitimate resources your policy is accidentally blocking (or catch real attack attempts) without waiting for a user to report a broken page. Set it via the HTTP header, since it's ignored in the <meta> tag form.