CSP Generator
Build a Content-Security-Policy header for your site's resources.
Content-Security-Policy (CSP) is a security header that tells the browser which origins may serve scripts, styles, images, fonts and network connections. A well-tuned CSP dramatically reduces the impact of XSS (cross-site scripting), data exfiltration and clickjacking. This CSP generator lets you toggle allowed sources per directive such as default-src and script-src, add custom domains, and assembles the matching header string in real time.
You apply the result via the Content-Security-Policy response header or a <meta>tag. A good rollout is to ship it first in report-only mode (Content-Security-Policy-Report-Only), collect violation reports, refine the policy, and only then enforce it. Everything runs entirely in your browser and nothing you enter is ever sent anywhere.
Enable the directives you want, pick source keywords, or enter custom domains.
default-src 'self'
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
Understanding the key directives
CSP grants allowed origins per resource type. The most important starting point is default-src, which acts as the fallback policy for any resource type without its own directive.
- default-src: fallback applied when a more specific
*-srcis absent. - script-src: where JavaScript may be loaded and executed. The most security-sensitive one.
- style-src: origins for stylesheets and inline styles.
- img-src: origins images may be loaded from.
- font-src: origins for web fonts.
- connect-src: origins for fetch, XHR, WebSocket and EventSource connections.
- frame-src: origins allowed to be embedded as iframes.
Source keywords and the danger of unsafe-inline
Each directive accepts a mix of keywords and domains. 'self' means the same origin (scheme + host + port); 'none' blocks every origin. data: allows inline data URIs and https: allows any HTTPS origin.
- 'unsafe-inline' permits inline
<script>code, inline handlers likeonclick, and inline<style>. Enabling it onscript-srceffectively cancels CSP's XSS protection, so avoid it and use nonces or hashes instead. - Overly broad sources like https: or a wildcard (
*) can allow untrusted third-party resources. Narrow them to the specific CDN and API domains you actually use. - 'none' is only meaningful on its own. Combined with other sources it has no effect.
Applying it and rolling out gradually
- Deploy first with the
Content-Security-Policy-Report-Onlyheader to collect violations. - Review the reports and add the origins your site legitimately needs to each directive.
- Once violations stop, switch to the enforcing
Content-Security-Policyheader.
For the strongest XSS protection, drop 'unsafe-inline' from script-src and rely on a nonce or hash based approach. Once deployed, use the security headers checker to confirm the CSP is actually being sent in your responses.
Source expression quick reference
Here are the source expressions you will most often place in a directive and what each one allows. The quotes in 'nonce-...', 'sha256-...' and'strict-dynamic' must appear literally in the header string (e.g. script-src 'nonce-r4nd0m').
| Source expression | Allows | Notes |
|---|---|---|
'self' | Same origin (scheme+host+port) | Subdomains are NOT included; add cdn.example.com separately |
'none' | Blocks everything | Only valid on its own |
'unsafe-inline' | Inline scripts/styles and inline handlers | Ignored by modern browsers when a nonce/hash is present |
'unsafe-eval' | eval(), new Function(), string setTimeout | Required by some legacy libraries / template engines |
'nonce-...' | Inline tags carrying the matching nonce | Must be a fresh random value on every request |
'sha256-...' | Inline code whose hash matches | Recompute the hash if even one character of the code changes |
'strict-dynamic' | Scripts dynamically loaded by a nonce/hash-trusted script | Turns off host and https: allowlists once enabled |
data: | data URIs | Common on img-src but dangerous on script-src |
frame-ancestors is not frame-src
The names look alike but they point in opposite directions. frame-src controls which origins your page may embed as iframes, while frame-ancestors controls which origins may embed your page as an iframe (clickjacking defence, the modern replacement forX-Frame-Options). To stop clickjacking use frame-ancestors 'self' orframe-ancestors 'none'. Note that frame-ancestors does not work from a<meta> tag, so it must be sent as a response header.
Reading a worked example
Imagine a policy for an SPA that uses Google Fonts and its own API:
default-src 'self'; script-src 'self' 'nonce-AbC123'; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:; connect-src 'self' https://api.example.com; frame-ancestors 'none'
- An inline bootstrap script runs only if it carries the same nonce:
<script nonce="AbC123">. - Google Fonts splits the CSS (
fonts.googleapis.com) from the font files (fonts.gstatic.com), so both origins are required. - Icons are inlined as base64, so
img-srcallowsdata:. connect-srclists only the first-party API, blocking fetch/XHR exfiltration to any other domain.frame-ancestors 'none'blocks any outside site from framing the page (clickjacking).
Common pitfall
- It is easy to assume
'self'covers subdomains. A CSP served fromexample.comdoes NOT includecdn.example.comunder'self'— list each subdomain explicitly. - People often think adding both a nonce/hash and
'unsafe-inline'is "safe", but CSP3 browsers ignore'unsafe-inline'whenever a nonce/hash is present (it only serves as a fallback for old browsers). Conversely, reusing a fixed nonce across requests destroys the protection — it must be regenerated per request.
Frequently asked questions
Is default-src alone enough?
Should I never use unsafe-inline?
Where do I put the generated CSP?
What if a strict policy breaks my site?
Are the domains I enter sent to a server?
Related guides
- Essential Security Headers Guide (CSP, HSTS, X-Frame-Options)The security headers you must set, what each does, recommended values and common mistakes.