Skip to content

CSP Builder

Build a Content Security Policy visually with presets, then copy the header, Nginx or Apache snippet.

How it works

A Content Security Policy is a response header that tells the browser which sources may load each resource type — scripts, styles, images, fonts, connections, frames. It is the strongest practical defense against XSS: even if attacker markup lands in your page, a strict script-src 'self' stops it from executing. The hard part is not the concept, it is the syntax: one wrong token and either the policy breaks the site or silently protects nothing.

The builder gives every directive its own enable toggle and value field with sane defaults — default-src 'self', object-src 'none', frame-ancestors 'none', base-uri 'self', form-action 'self' — so the starting point is strict rather than empty. Presets cover the three realities: a strict static site, a static site with Google Fonts (style and font exceptions), and an SPA calling its own API.

Output comes in three forms: the bare header value, a ready add_header line for Nginx, and the Apache equivalent. upgrade-insecure-requests and block-all-mixed-content are one checkbox each — free wins on any HTTPS site.

The deployment advice matters as much as the syntax: ship first as Content-Security-Policy-Report-Only, collect violations, fix what breaks, then enforce. The headers analyzer pairs with this tool to grade what you deploy.

Worked example

Build the strict static-site baseline: everything from self, no objects, no framing, HTTPS upgrade forced.

DirectiveValueBlocks
script-src 'self'First-party scripts onlyInjected inline or third-party JS.
object-src 'none'No pluginsFlash/Java-style legacy payloads.
frame-ancestors 'none'No embeddingClickjacking.
base-uri 'self'No base hijackRelative-URL redirection via injected <base>.
  1. Start strict: Enable the default directives — self everywhere, none for objects and framing.
  2. Add real exceptions: Only the sources your site actually loads: fonts, API, analytics.
  3. Copy the snippet: Nginx add_header or Apache Header line, ready to paste.
  4. Report, then enforce: Run report-only first, fix violations, then switch to enforcement.

Header: default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests — a one-line policy that neutralizes most injection classes.

Common errors and edge cases

  • unsafe-inline to "make it work". It removes most XSS protection. Move inline scripts to files or use nonces/hashes — every unsafe-inline needs a justification.
  • Enforcing before reporting. Deploying a strict untested policy breaks production. Content-Security-Policy-Report-Only first, enforce after violations reach zero.
  • Forgetting connect-src. fetch/XHR/WebSocket are governed by connect-src — an SPA with the default policy may lose all API calls.
  • Meta-tag mismatch. frame-ancestors, report-uri and sandbox are ignored in meta-tag CSPs. Deliver the policy as an HTTP header.
  • Data-URI creep. img-src data: is common and fine; data: in script-src or style-src reopens injection. Scope data: to images and fonts only.

Code equivalents

The two server snippets the tool generates, plus the report-only variant to deploy first.

ServerSnippet
Nginxadd_header Content-Security-Policy "default-src 'self'; ..." always;
ApacheHeader always set Content-Security-Policy "default-src 'self'; ..."
Report firstContent-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Frequently asked questions

What is the minimal useful CSP?

default-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'. Four directives that block plugins, framing and base hijack while keeping the site functional — then tighten script-src deliberately.

Should I use nonces or hashes for inline scripts?

Nonces when your HTML is dynamically generated per request (a fresh random value each time); hashes for static inline blocks. Both beat 'unsafe-inline' decisively.

Why did my SPA break after enabling CSP?

Almost always connect-src (fetch/XHR to your API) or img-src data:/blob: for previews. Add the API origin to connect-src and keep data:/blob: limited to img-src.

Is report-only worth the trouble?

Yes — it is the only safe way to discover every dependency before enforcement. Ship report-only, fix violations for a week, then enforce the same policy.

Does CSP replace output encoding?

No. CSP is the safety net for when encoding fails; context-correct escaping remains the primary fix. You want both: encoding stops injection, CSP stops execution.

Privacy note

All processing happens in your browser. The values you enter never leave your device and are never transmitted to ToolPlex.