Content Security Policy Generator

Build a Content-Security-Policy from a safe default, add the third-party services you use, and copy it for Nginx, Apache or a meta tag.

Runs entirely in your browser. Nothing you add is sent to us.

Create a free account to use the Content Security Policy Generator

Free forever for this tool. Takes a few seconds — then you come straight back here.

  • All 150 free tools, one login
  • Free website audit with fixes
  • Search Console dashboard
  • Free keyword rank tracker

Already have an account? Sign in

Published it? Verify it with the free Headers checker →

Content Security Policy Generator — csp generator

Our CSP generator builds a Content-Security-Policy header from a safe starting point, adds the third-party services you use, and gives you the result ready to paste into Nginx, Apache, a raw header or a meta tag. It runs entirely in your browser, so nothing you type is sent to us. It suits UK small businesses, developers and agencies who want the protection of a content security policy without writing every directive by hand or breaking the site on day one.

How to use the CSP generator

  1. 1 Tick the services you useChoose any of the presets: Google Analytics 4 or Tag Manager, Google Fonts, YouTube embeds and Stripe Checkout or Elements. Their domains are added to the right directives automatically.
  2. 2 Set the optionsLeave report-only mode on for the first deployment, decide whether your theme needs inline styles, and keep upgrade insecure requests on unless you have a reason not to.
  3. 3 Fine-tune the directivesEdit any directive as space-separated sources, for example adding a CDN or a booking widget domain. Keep quotes around keywords such as 'self' and 'none'.
  4. 4 Copy the output for your platformPick the Nginx, Apache, Header or Meta tag tab and copy the line. Then deploy it and check the result with our security headers checker.

Roll it out in report-only mode

A strict CSP can break scripts, styles and embeds you forgot about. Deploy it as Content-Security-Policy-Report-Only first, watch the browser console for violations, adjust, then switch to the enforcing header.

Why unsafe-inline is a compromise

Allowing inline scripts removes most of the protection CSP gives against injected code. Inline styles are a smaller risk and often needed by themes; inline scripts are better moved to files or allowed with nonces.

What a CSP generator does and why it helps

A Content-Security-Policy is a response header that tells the browser exactly where a page may load scripts, styles, images, fonts, frames and network requests from. If an attacker manages to inject a script tag through a vulnerable plugin, form or third-party library, a good policy stops the browser running it because its source is not on the list. It is one of the most effective defences against cross-site scripting, and it also controls who can frame your pages.

The difficulty is that a policy has to list everything your site legitimately uses, written in a precise syntax where a missing quote changes the meaning. A CSP generator removes the guesswork: you start from a tight default, add known services with a click, and get a correctly formatted policy for the place you will deploy it.

How our Content Security Policy builder works

The generator starts with a deliberately strict policy. Scripts, styles, fonts and network connections are limited to your own origin, images may also use data: URIs, plugins via object-src are switched off with 'none', and base-uri, form-action and frame-ancestors are limited to 'self'. The frame-src directive starts empty and is left out of the output, so embedded frames fall back to default-src and are only allowed from your own site.

Each preset merges its domains into the matching directives. Google Analytics 4 and Tag Manager add Google's script, image and connection hosts, including wildcard Google Analytics domains so regional collection endpoints are covered. Google Fonts adds fonts.googleapis.com to style-src and fonts.gstatic.com to font-src. YouTube adds the standard and privacy-enhanced embed domains to frame-src, and Stripe adds its script, frame and API hosts. Duplicates are removed automatically.

Three options change the output. Report-only mode, on by default, switches the header name to Content-Security-Policy-Report-Only. Allow inline styles adds 'unsafe-inline' to style-src. Upgrade insecure requests appends the upgrade-insecure-requests directive. Everything is calculated in your browser as you click, and the policy updates instantly.

Understanding the key CSP directives

Keywords such as 'self', 'none' and 'unsafe-inline' must be wrapped in single quotes. Host names and schemes such as https://example.com or data: are written without quotes.

  • default-src: the fallback for any fetch directive you do not set explicitly.
  • script-src: where JavaScript may load from. This is the directive that matters most for stopping injected code.
  • style-src: stylesheets and, if 'unsafe-inline' is present, inline style attributes and style blocks.
  • img-src and font-src: images and web fonts. data: in img-src allows small inline images that many themes use.
  • connect-src: destinations for fetch, XHR and WebSocket requests, which analytics and payment scripts rely on.
  • frame-src: which sites your pages may embed, such as YouTube or a payment form.
  • frame-ancestors: which sites may embed your pages, the modern replacement for X-Frame-Options.
  • object-src 'none': blocks legacy plugin content, which no modern site needs.
  • base-uri and form-action: stop injected base tags redirecting relative links, and stop forms posting data to another site.

Deploying your policy on Nginx, Apache, Cloudflare and WordPress

Nginx: paste the add_header line from the Nginx tab inside your server block, run nginx -t, then reload. If a location block has its own add_header lines, add the policy there too, because Nginx does not merge headers between levels.

Apache and cPanel hosting: paste the Header always set line from the Apache tab into your virtual host or the .htaccess file in the site root, which you can edit in cPanel File Manager. mod_headers must be enabled, which it is on almost all shared hosting.

Cloudflare: copy the raw value from the Header tab and add it as a response header in a transform rule. This applies the policy at the edge without touching your server, and makes it easy to switch from report-only to enforcing later.

WordPress: a security plugin with a custom headers field can take the value from the Header tab, or a developer can send it from the send_headers action. Use the meta tag only as a last resort on hosts that give you no header control, because it cannot carry frame-ancestors or report-only mode; the generator strips frame-ancestors from the meta output for that reason.

Testing in report-only mode before you enforce

With report-only mode on, the browser applies the policy in theory but blocks nothing. Instead, every resource that would have been blocked is logged in the developer console with the directive it broke and the URL it came from. Browse your important pages with the console open: homepage, contact form, checkout, booking pages and anything with an embed.

For each violation, decide whether the resource is genuinely needed. If it is, add its origin to the matching directive in the generator and copy the new line. If you do not recognise it, find out what it is before allowing it, as it may be an old plugin or a script you no longer use.

The generator does not add a reporting endpoint. If you want violations sent to a collector rather than only shown in the console, add report-uri and report-to to the copied value yourself, together with a Reporting-Endpoints header. Once the console stays clean across your key pages for a week or so, untick report-only, deploy the enforcing header and keep an eye on it after each plugin or marketing tag change.

Inline scripts, nonces and CSP best practice

The generator never adds 'unsafe-inline' to script-src, because doing so allows almost any injected script to run and removes most of the value of the policy. If your site relies on inline scripts, the better options are to move them into files on your own domain, or have your application add a random nonce to each script tag and to the policy on every response. Tag Manager custom HTML tags and some page builders inject inline code, so test them carefully.

  • Start strict and add sources only when the console shows they are needed.
  • Avoid broad sources such as https: or * in script-src, which allow scripts from anywhere.
  • Never add data: to script-src.
  • Prefer the HTTP header over the meta tag, and send only one copy of the policy.
  • Review the policy whenever you add a new tool, widget or tracking tag.

Examples you can copy

The generator's default output for Nginx in report-only mode

add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests" always;

Enforcing policy for Apache with the Google Analytics and Google Fonts presets ticked

Header always set Content-Security-Policy "default-src 'self'; script-src 'self' https://www.googletagmanager.com; style-src 'self' https://fonts.googleapis.com; img-src 'self' data: https://*.google-analytics.com https://*.googletagmanager.com; font-src 'self' https://fonts.gstatic.com; connect-src 'self' https://*.google-analytics.com https://*.analytics.google.com https://*.googletagmanager.com; frame-ancestors 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; upgrade-insecure-requests"

Adding a reporting endpoint by hand to a report-only header (Nginx)

add_header Reporting-Endpoints 'csp="https://example.co.uk/csp-reports"' always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; report-uri https://example.co.uk/csp-reports; report-to csp" always;

Common mistakes to avoid

Writing self without quotes

Unquoted, self is read as a host name called self, so your own scripts are blocked. Always write 'self', 'none' and other keywords in single quotes.

Expecting upgrade-insecure-requests to work in report-only mode

Browsers ignore this directive in a report-only policy and only apply it when the policy is enforced. Check for mixed content separately while testing.

Sending the policy twice

If a header and a meta tag, or a CDN and a server, both send a policy, the browser enforces both and a resource must pass every one. Keep a single copy.

Adding unsafe-inline to script-src to silence errors

It makes the console quiet by switching off the protection you added the policy for. Move inline scripts into files or use nonces.

Leaving report-only on forever

Report-only blocks nothing, so the site gains no protection. Set a date to review the violations and switch to the enforcing header.

Frequently asked questions

Something loads from a source the policy does not allow — an analytics script, a font, an iframe. The browser console names the blocked URL and the directive; add that source to the matching directive.

Prefer the HTTP header. A meta tag works for most directives but cannot set frame-ancestors or report-only mode.

It controls which sites may embed your pages in a frame, protecting against clickjacking. 'none' blocks all framing; 'self' allows only your own site.

It is an allow-list sent with each page that tells the browser which sources of scripts, styles, images and frames are trusted. Anything not on the list is blocked, or reported in report-only mode.

No. The browser checks each resource against the policy as it loads, which takes a negligible amount of time. A strict policy can even prompt you to remove unused third-party scripts.

Yes, but the browser enforces all of them together, so a resource must be allowed by every policy. It is simpler and safer to send one.

frame-src controls which sites your pages can embed. frame-ancestors controls which sites can embed your pages, protecting against clickjacking.

No. It runs in your browser and nothing you enter is sent to our servers. Copy the output before leaving the page.

It can if Tag Manager loads scripts or inline code from sources the policy does not allow. Tick the Google Analytics 4 / Tag Manager preset, test in report-only mode, and add any extra hosts your tags use.

Learn more

Free website audit

See how your site scores, free

Speed, SEO, DNS, email (SPF/DKIM/DMARC) and security in one scan, with a prioritised fix list.