CSP Header Generator
Build a Content-Security-Policy and copy a ready HTTP header or meta tag.
-
1Enter data
Enter content, paste text or load a file from disk. -
2Click the button
The tool will immediately process your data in the browser. -
3Get the result
Copy the finished text or save the file to your device.
return "Result ready in 0.1s";
}
Rate this tool:
Related tools
Other tools you may find usefulCSP header generator - a Content-Security-Policy without guesswork
The CSP header generator assembles a Content-Security-Policy from the ten directives that decide how well a page resists code injection. Fill in the source lists, choose an HTTP header or a <meta> tag, and copy the finished line into your server configuration.
What this tool really does
The form takes ten directives with source lists, from default-src to frame-ancestors. Empty fields are skipped, extra whitespace collapsed and repeated sources inside one directive dropped: the header travels with every response, so its length matters. Semicolons and double quotes are filtered out so a pasted value cannot break the header.
You get the result as a Content-Security-Policy: … line for the server, or as a <meta http-equiv> tag. The HTTP header is the complete version: the meta variant supports neither frame-ancestors nor report-uri nor sandbox, so the generator leaves it out in that mode.
The directives the generator sets
| Directive | What it controls | Start |
|---|---|---|
| default-src | Fallback for the other *-src directives | 'self' |
| script-src | JavaScript files, modules, workers | 'self' |
| style-src | Stylesheets and styles embedded in HTML | 'self' |
| img-src | Images, including data: and blob: | 'self' data: |
| connect-src | fetch, XHR, WebSocket, beacon | 'self' |
| object-src | Plugins: object, embed | 'none' |
| base-uri | Values allowed for the base tag | 'self' |
| form-action | Endpoints forms may submit to | 'self' |
| frame-ancestors | Who may embed the page in a frame | 'none' |
Two entries on that list close the common ways around a policy. object-src 'none' disables legacy plugins that used to run code despite a strict script-src. base-uri 'self' blocks a swapped <base href> that would point relative script paths at a foreign server.
How to roll out CSP without breaking the site
- Send the policy under the
Content-Security-Policy-Report-Onlyname first. The browser then blocks nothing and only reports violations. - Click through the site, especially pages with maps, payments, chat widgets and video - that is where missing domains surface.
- Add the addresses from the reports and confirm the header reaches the browser with the HTTP headers analyzer.
- Once the reports stay quiet for a few days of normal traffic, rename the header to
Content-Security-Policyand it starts to enforce.
You add the header in the server configuration: on Apache through Header always set in .htaccess (the .htaccess file generator helps), on nginx through add_header in a location block (nginx location block configurator).
Header always set Content-Security-Policy "default-src 'self'; object-src 'none'"
Why 'unsafe-inline' in script-src removes the protection
CSP stops XSS at one point: it refuses to run a script you never declared. An injected <script>alert(1)</script> is precisely an inline script. Once 'unsafe-inline' appears in script-src, the browser executes any code embedded in the HTML, including code that arrived through a comment field. The most common attack path then goes through untouched. The same applies to 'unsafe-eval', which reopens eval().
'unsafe-inline' or 'unsafe-eval' lands in script-src or default-src. In style-src the risk is smaller, so the default policy allows inline styles there.Instead of 'unsafe-inline', use a single-use nonce: the server draws a random value for every response and puts it in the header and in the nonce attribute of trusted tags. An attacker does not know that value, so the injected code never runs. For fixed blocks a 'sha256-…' hash of the exact script body works instead - the crypto hash generator produces the digest.
frame-ancestors, X-Frame-Options and upgrade-insecure-requests
frame-ancestors decides who may place the page in an iframe, and it supersedes the older X-Frame-Options. The old header only understands DENY and SAMEORIGIN, accepts no domain list, and its ALLOW-FROM variant never worked in Chrome. When both are present, browsers honour the CSP directive.
It is also worth adding upgrade-insecure-requests. This directive takes no source list - its presence makes the browser rewrite http:// addresses to https:// before the request goes out. It rescues sites after an HTTPS migration with old links to images over HTTP. To see what else loads unencrypted, use the mixed content detector.
Frequently asked questions
Is the meta version of CSP equivalent to the header?
No. The <meta http-equiv> version supports most directives, but the browser ignores frame-ancestors, report-uri and sandbox in it. The rules apply only once the tag is parsed, so resources above it may already have loaded.
Where do I start if the site has no CSP at all?
With default-src 'self', object-src 'none' and base-uri 'self' in report-only mode. Those three rarely break anything and cut off the simplest vectors. Then add the domains your reports name: font CDNs, analytics, maps.
Why is the policy blocking my own script?
Usually because the script is embedded in the HTML rather than loaded from a file, and 'self' covers files, not inline code. The second is event handlers in attributes such as onclick. The browser console names the directive that blocked each request.
Does CSP replace input sanitisation?
No, it is a second line of defence. Escaping input prevents the injection; CSP limits the damage if one succeeds. It does nothing about SQL injection or CSRF.
Does CSP affect performance or SEO?
The header is a few hundred bytes per response, so the cost is negligible. An over-strict policy can still block the scripts that render your content, and then the crawler sees an empty page.