Content-Security-Policy Builder
Build a CSP header from per-directive source lists, with three starter presets and live warnings for the dangerous wildcards.
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'">
An empty directive falls through to default-src. Set default-src 'self' first, then narrow individual sources.
How to use
- Start from a preset (Strict locks everything to 'self', Relaxed allows inline + wildcards, API-only blocks navigation).
- Edit each directive — leave a field blank to drop it.
- Turn on report-only when shipping a new policy: violations are reported but not blocked.
About this tool
ShowHide
Composes a Content-Security-Policy header from a directive-by-directive form. Each directive accepts a space-separated source list (keywords like 'self', 'none', 'unsafe-inline', or scheme/host sources). The tool flags policies that contain unsafe-inline, unsafe-eval, or a wildcard, omits empty directives from the output, and emits both the response header form and the equivalent <meta> tag (in report-only mode only the header, because browsers ignore a report-only policy delivered by <meta>). Switch to report-only mode while you're rolling a new policy out to production.
The two output forms are not equivalent, despite looking it. A <meta> tag cannot carry frame-ancestors, report-uri or sandbox, and it takes effect only from where it appears in the document, so anything the parser has already reached is unprotected. The response header has none of those limits and is the form to prefer whenever you control the server.
default-src is a fallback and not a floor. Directives that are absent inherit from it, but any directive you do write replaces it outright for that resource type, so adding script-src https://cdn.example.com to a policy with a strict default-src 'self' drops 'self' for scripts unless you list it again. Several directives, frame-ancestors and base-uri among them, do not fall back to default-src at all and are simply unrestricted when omitted.
'unsafe-inline' deserves the warning it gets, because it disables the protection most policies exist for. It is also silently ignored in any policy that carries a nonce or a hash, which is the modern way to allow specific inline scripts, and that interaction is a common source of a policy that behaves differently from how it reads.
Report-only mode is the right way to deploy. The browser evaluates the policy, reports what would have broken and blocks nothing, which surfaces the third-party scripts and inline handlers you had forgotten. Do note that the two headers are independent: shipping a report-only policy does not weaken an enforcing one you already serve, and neither does it enforce anything on its own.
Frequently asked questions
Header or <meta> tag — which should I use?
The HTTP header is preferred. The <meta> form is convenient when you can't edit response headers (static hosts, etc.), but it can't define frame-ancestors or report-uri/report-to, so it's strictly less powerful.
Why is the wildcard a warning?
* in a source list matches any URL, defeating the policy entirely. Pin sources to specific origins or use 'self' instead — if you genuinely need third-party scripts, list them explicitly.
How do I roll out a policy without breaking the site?
Send it as Content-Security-Policy-Report-Only first. The browser evaluates the policy and reports what would have been blocked, while still loading everything, so you can collect violations from real traffic before enforcing. Move to the enforcing header once the reports are quiet — a policy written from a guess about your own page almost always blocks something you forgot.
Why is my inline script still blocked when I allowed the domain it came from?
Because a host source only covers files fetched from that host. Code written inside the page has no URL to match, so it needs 'unsafe-inline', a hash of its exact contents, or a nonce that the server puts on both the header and the tag. The same applies to inline styles, to a style attribute, and to event handler attributes such as onclick.
Related tools
CSP Hash Generator
Compute the sha256 / sha384 / sha512 base64 hash an inline <script> or <style> block needs to be whitelisted by a Content-Security-Policy.
Network
HSTS Header Builder
Compose a Strict-Transport-Security header — max-age, includeSubDomains, preload — with a live preload-list eligibility check.
Network
SPF Record Builder
Compose a Sender Policy Framework TXT record from mechanisms, IPs and includes — with a live DNS-lookup counter and warnings.
Network
Permissions-Policy Header Builder
Build the Permissions-Policy header: set camera, microphone, geolocation, payment, fullscreen and 20+ other browser features by origin allowlist.
Network
Referrer-Policy Header Builder
Pick a Referrer-Policy value and see exactly what Referer header outbound requests will send — same-origin, cross-origin HTTPS, HTTPS→HTTP downgrade.
Network
DNSSEC Calculator — DS Record & NSEC3 Hash
Turn a DNSKEY into the DS record your registrar wants — key tag and all three digest types — or hash a name the way NSEC3 does.
Network