A browser-based tool for building Content Security Policy (CSP) headers. Enable directives, pick common keywords, add custom source URLs, review a live security score, and copy the generated policy—or ready-made snippets—for your web server.
The app runs entirely in the browser for policy editing. Import from URL uses a small server-side lookup (Vite middleware in development, Cloudflare Pages Functions in production) so you can fetch an existing policy from HTTP headers or HTML meta tags. Paste headers or policy runs entirely in the browser—paste a full response header block or a single Content-Security-Policy line to extract and import the CSP.
Content Security Policy is one of the most effective mitigations against cross-site scripting (XSS) and related injection attacks, but the syntax is easy to get wrong. CSP Playground lowers the barrier to authoring a correct policy by:
- Mapping every standard directive to an accessible form control
- Explaining sandbox flags and linking to MDN documentation
- Generating nonces, style-attribute hashes, and server config snippets
- Scoring your policy heuristically and suggesting concrete improvements
If a site has no CSP yet, the importer links to why-csp.html—a short guide on why and how to adopt a policy.
- Beginner, Intermediate, and Advanced starter policies via Choose a preset
- Applies immediately when the form is empty; otherwise asks for confirmation before replacing your work
- Each preset enables a sensible subset of directives with documented keywords and sources
- Form-based editor for all standard CSP directives, grouped by category:
- Fetch (
default-src,script-src,style-src, …) - Document (
base-uri,sandbox, …) - Navigation (
form-action,frame-ancestors, …) - Reporting (
report-uri,report-to, …) - Other (
upgrade-insecure-requests, Trusted Types, …)
- Fetch (
- Enable/disable each directive independently
- Keyword dropdown for common values (
'self','none','unsafe-inline','strict-dynamic', schemes, and more) - Multiple custom source inputs per directive with add/remove controls
- Sandbox directive — checkbox list for every sandbox flag, each with a ? help icon showing a description on hover/focus
- Trusted Types directives with appropriate single- or multi-value controls
- MDN documentation links beside each directive name
Import an existing CSP into the builder from a live URL or pasted text:
- Import from URL — enter a site URL and fetch its CSP from:
Content-Security-Policy/Content-Security-Policy-Report-Onlyresponse headers<meta http-equiv="Content-Security-Policy">tags in HTML
- Paste headers or policy — paste directly into the form (no server lookup):
- Full HTTP response headers;
Content-Security-Policyis extracted automatically - A single
Content-Security-Policy:header line on its own
- Full HTTP response headers;
- Pre-fills the builder form from the parsed policy
- Validate CSP checks formatting and suggests corrections (URL and paste import)
- Graceful handling when no policy is found (links to the why-CSP guide)
- Script/style nonce helper (on
script-src,script-src-elem,style-src,style-src-elem):- Generates example cryptographically random nonces and matching HTML snippets for inline or external scripts/stylesheets
- Adds
'nonce-…'to the directive - Production note: in production, generate a new nonce on every HTTP response on the server and inject the same value into both your CSP header and your HTML — never reuse a fixed nonce copied from this tool
- Style attribute hash helper (on
style-src-attr):- SHA-256 hashes the exact
style="…"attribute value via Web Crypto - Adds
'sha256-…'and'unsafe-hashes'when needed - Copies a sample element with the hashed attribute
- SHA-256 hashes the exact
- Live preview of the policy value and full HTTP header line
- Toggle enforce vs Content-Security-Policy-Report-Only for safe rollout
- One-click copy for policy value, header, or web-server snippet
- Export snippets for Apache, Nginx, Caddy, LiteSpeed, Microsoft IIS, Cloudflare Pages, Netlify, Firebase Hosting, Vercel, Traefik, and Envoy
- HTML-only CSP option for servers that support scoping headers to HTML responses (Apache, Nginx, Caddy, LiteSpeed, Cloudflare Pages middleware, Firebase Hosting); unsupported servers show a disabled checkbox with an explanation
- Per-server setup notes (e.g. Cloudflare Pages
_headersvsfunctions/_middleware.tsfor HTML-only) - Deployment disclaimer with link to MDN’s safe CSP implementation guide
- Real-time letter grade (Poor → Excellent) with numeric score
- Breakdown of factors that helped or hurt the score
- Actionable recommendations with estimated point gains
- Click a recommendation to scroll to the relevant directive in the form
- Report-only mode is reflected in scoring (violations are not blocked)
- Semantic HTML, labels, focus styles, and
aria-liveregions for dynamic updates - Keyboard-accessible controls and tooltips
- Preset and confirmation flows use a native
<dialog>modal with focus trap,inerton the main app, and focus restoration on close
| Layer | Choice |
|---|---|
| UI | TypeScript, vanilla DOM (no framework) |
| Bundler | Vite |
| Package manager | Yarn v1 (yarn.lock is canonical) |
| Tests | Vitest + jsdom, Istanbul coverage |
| Lint / format | Biome |
| Deployment | Static dist/ on Cloudflare Pages + Pages Functions |
- Node.js 22.16.0 (see
.nvmrc; matches Cloudflare Pages v3) - Yarn 1.22.22 (classic; set
YARN_VERSION=1.22.22on Cloudflare Pages)
yarn installyarn dev
# or
yarn startOpen http://localhost:5173. URL import works via a Vite middleware shim—you do not need Wrangler for day-to-day UI work.
yarn buildStatic files are output to dist/. Preview the production build with:
yarn previewyarn test # Run once
yarn test:watch # Watch mode
yarn test:coverage # Coverage with thresholds (100% lines/functions, 99% statements, 93% branches)Playwright runs against the production build served by vite preview (includes the CSP lookup middleware):
yarn build # Required before first e2e run
yarn test:e2e # Headless Chromium smoke suite
yarn test:e2e:ui # Interactive Playwright UI
yarn playwright install chromium # One-time browser install locallyyarn typecheck # Client (src/) + server/functions shared codeyarn lint # Biome check (CI runs this)
yarn lint:fix # Apply safe fixes and formatting
yarn format # Format onlyDirect dependencies are pinned to exact versions. After any dependency update, run verification once when all changes are complete:
yarn verify:depsSee AGENTS.md for the full dependency policy.
- Optionally click Choose a preset for a beginner, intermediate, or advanced starter policy.
- Optionally use Import existing policy at the top—fetch from a URL, or paste response headers / a
Content-Security-Policyheader line—and click Import CSP. - Enable a directive (e.g.
default-src) using its checkbox. - Add keywords from the dropdown or enter custom sources (e.g.
https://cdn.example.com). - Use nonce or style-hash helpers where inline content needs to be allowed safely.
- Review the security score panel and apply recommendations if helpful.
- Review the generated policy in the output panel.
- Copy the policy, full header, or web server configuration snippet.
Toggle Content-Security-Policy-Report-Only to generate a report-only header for testing before enforcement.
src/csp/ Policy parsing, building, scoring, keywords, hashes, presets, server exports
src/ui/ Form components, output panel, security score, preset picker, modal, helpers
src/api/ Client fetch wrapper for CSP lookup
server/ Shared lookup logic + Vite dev middleware
functions/api/ Cloudflare Pages Function (production API)
tests/ Vitest unit and integration tests
docs/ Architecture and contributor docs
public/data/ Sandbox flag descriptions (loaded for tooltips)
URL import in production uses Cloudflare Pages Functions. The function at functions/api/csp-lookup.ts exposes POST /api/csp-lookup on Cloudflare’s edge—the same contract as local development.
- Connect this repository to Cloudflare Pages.
- Build command:
yarn build - Build output directory:
dist - Root directory / path: leave empty (repo root)
Cloudflare reads pages_build_output_dir from wrangler.toml and deploys functions/ alongside static assets. No deploy command or separate Worker is required.
Test static assets plus the Pages Function locally:
yarn pages:devyarn pages:deployRequires Wrangler authentication (wrangler login).
- AGENTS.md — conventions for coding agents (also available as
AGENT.md) - docs/ARCHITECTURE.md — module boundaries, data flow, and API contract
- llms.txt — concise project summary for LLM crawlers and agents
.cursor/rules/— Cursor-specific rules for dependency pinning and project context- TSDoc comments on exported APIs in
src/,server/, andfunctions
Two bots run side by side with non-overlapping scopes:
| Bot | Scope |
|---|---|
| Renovate | npm / Yarn packages (package.json, yarn.lock) |
| Dependabot | GitHub Actions pins in .github/workflows/ |
Both label PRs dependencies and run on the same daily schedule (06:00 Europe/London). Either bot may open a security advisory PR for npm; merge one and close any duplicate.