Content Security Policy (CSP) Generator

Understand every CSP directive, build secure policies, and deploy Content Security Policy headers that prevent XSS and data injection attacks.

What Is Content Security Policy?

Content Security Policy is an HTTP response header that provides a declarative allowlist of content sources for your web page. When a browser loads a page with a CSP header, it enforces the policy by blocking any resource that does not match the declared sources. CSP is the strongest browser-side defense against Cross-Site Scripting because it prevents injected scripts from executing even if an attacker successfully injects HTML into the page.

CSP was designed as a defense-in-depth layer. It does not replace input validation or output encoding — it catches the attacks that slip through those defenses. A well-configured CSP can neutralize stored XSS, reflected XSS, clickjacking, form hijacking, and malicious resource injection. Google's deployment of strict CSP across their properties eliminated entire classes of XSS bugs that had persisted for years.

CSP Directive Reference

default-src: The fallback directive for all resource types not explicitly configured. Setting default-src 'self' restricts all resources to the same origin by default. Every other directive overrides default-src for its specific resource type.

script-src: Controls which scripts can execute. This is the most critical directive for XSS prevention. Recommended: script-src 'nonce-{random}' 'strict-dynamic'. Avoid 'unsafe-inline' and 'unsafe-eval'.

style-src: Controls which stylesheets can be applied. style-src 'self' 'unsafe-inline' is common because inline styles are lower risk, but nonce-based style policies are more secure.

img-src: Controls which image sources are allowed. img-src 'self' data: https: allows same-origin images, data URIs, and any HTTPS image source.

font-src: Controls web font sources. font-src 'self' https://fonts.gstatic.com is typical for sites using Google Fonts.

connect-src: Controls which URLs the page can connect to via fetch, XMLHttpRequest, WebSocket, and EventSource. Critical for APIs: connect-src 'self' https://api.example.com.

frame-src: Controls which URLs can be loaded in iframes. frame-src 'none' prevents all framing. Use this to block clickjacking and rogue iframe injection.

object-src: Controls plugin content (Flash, Java applets). Always set object-src 'none' — plugins are a legacy attack vector.

base-uri: Restricts URLs for the <base> element. Set base-uri 'self' or base-uri 'none' to prevent base tag injection, which can redirect all relative URLs.

form-action: Controls where forms can submit. form-action 'self' prevents form hijacking where an attacker changes the form's action URL.

frame-ancestors: Controls which pages can embed this page in an iframe. Replaces the X-Frame-Options header. frame-ancestors 'none' prevents all framing (equivalent to X-Frame-Options: DENY).

worker-src: Controls sources for Worker, SharedWorker, and ServiceWorker scripts. Falls back to script-src if not set.

manifest-src: Controls which manifest files can be loaded. manifest-src 'self' restricts to same-origin manifests.

report-uri / report-to: Specifies where CSP violation reports are sent. Use report-uri /csp-report or the newer report-to directive with a Reporting API endpoint. Violation reports tell you when legitimate resources are blocked or when actual attacks are mitigated.

Common CSP Configurations

Strict policy (recommended):

Content-Security-Policy: default-src 'none'; script-src 'nonce-{random}' 'strict-dynamic'; style-src 'self' 'nonce-{random}'; img-src 'self' https:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none';

Starter policy for existing sites:

Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; object-src 'none'; frame-ancestors 'self';

Report-only for testing:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self'; report-uri /csp-report;

Nonce-Based CSP

Nonce-based CSP is the recommended approach for modern applications. Generate a cryptographically random nonce (at least 128 bits of entropy) for each HTTP response. Add this nonce to the CSP header and to every legitimate script tag. The browser will only execute scripts that carry the matching nonce, blocking all injected scripts.

<!-- Server generates: nonce="a1b2c3d4e5f6" -->
<script nonce="a1b2c3d4e5f6" src="/app.js"></script>

<!-- CSP header includes the same nonce -->
Content-Security-Policy: script-src 'nonce-a1b2c3d4e5f6' 'strict-dynamic';

With 'strict-dynamic', scripts loaded dynamically by nonced scripts are also trusted. This means you only need to add the nonce to your initial script tags — everything they import or create inherits trust.

CSP Violation Reporting

Set up a reporting endpoint to monitor CSP violations in production. Each violation report includes the blocked URI, the violated directive, the document URI, and a sample of the blocked content. Services like report-uri.com, Sentry, and custom logging endpoints can aggregate these reports. Monitor for patterns: a spike in violations from a specific directive may indicate an active XSS attack being mitigated by your policy.

Frequently Asked Questions

What is a Content Security Policy?
A Content Security Policy (CSP) is an HTTP response header that tells the browser which sources of content are allowed to load on a page. CSP prevents Cross-Site Scripting, clickjacking, and other code injection attacks by restricting where scripts, styles, images, fonts, and other resources can be loaded from. When a resource violates the policy, the browser blocks it and optionally reports the violation.
What is the difference between CSP Level 2 and Level 3?
CSP Level 2 introduced nonce-based and hash-based script allowlisting, the base-uri directive, and the form-action directive. CSP Level 3 added the 'strict-dynamic' keyword, the 'report-sample' keyword, and the worker-src directive. Level 3 also introduced navigate-to for controlling navigation targets. Most modern browsers support Level 3.
Should I use 'unsafe-inline' in my CSP?
Avoid 'unsafe-inline' for script-src because it defeats CSP's primary XSS protection. If inline scripts are allowed, any injected script will also execute. Instead, use nonce-based CSP or hash-based CSP. For style-src, 'unsafe-inline' is more acceptable because inline styles are a lower-risk vector, though nonce-based styles are still preferred.
How do I deploy CSP without breaking my site?
Start with Content-Security-Policy-Report-Only instead of Content-Security-Policy. This header logs violations without blocking resources, letting you identify what would break. Monitor the violation reports, adjust your policy to allow legitimate resources, and repeat until violations are only from actual threats. Then switch to the enforcing header.
What is strict-dynamic and when should I use it?
'strict-dynamic' tells the browser to trust scripts loaded by already-trusted scripts. When combined with a nonce, you only need to add the nonce to your top-level scripts — any scripts they dynamically load are automatically trusted. This simplifies CSP for applications using script loaders, tag managers, or dynamically created script elements.

Written by Michael Lip — security tools at LochBot