EN DE

Content Security Policy Deployment Guide

Copy-paste CSP examples for every major platform — Apache, Nginx, WordPress, Node.js, Cloudflare and Vercel. Every snippet on this page uses a generic starter policy; to generate one tailored to your actual website, run a free scan.

Start with Report-Only mode. Deploy your CSP as Content-Security-Policy-Report-Only first. The browser logs violations to the console without blocking anything. Monitor for 1–2 weeks, fix the warnings, then switch to the enforcing Content-Security-Policy header. This prevents breaking your site the moment you roll out.

Platforms

Jump to the platform you're using:

Apache (.htaccess)

The most common deployment target. Drop this in the .htaccess file at your document root. Make sure mod_headers is enabled.

<IfModule mod_headers.c>
  Header always set Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'"
</IfModule>

Once you're confident the policy doesn't break anything, switch Content-Security-Policy-Report-Only to Content-Security-Policy to start enforcing.

Read the full Apache guide →

Nginx

Add this inside your server { } block (typically in /etc/nginx/sites-enabled/your-site):

add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'" always;

The always flag ensures the header is set on error responses too (404, 500), not just successful ones.

Read the full Nginx guide →

WordPress (functions.php)

Add this to your theme's functions.php (or better: a custom plugin, so a theme update doesn't wipe it out):

add_action('send_headers', function() {
    header("Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'");
});

WordPress almost always needs 'unsafe-inline' in script-src and style-src because core, themes and many plugins rely on inline scripts and styles.

Read the full WordPress guide →

Node.js / Express

Set the header via Express middleware. For anything beyond a trivial app, use the Helmet package which handles edge cases for you.

app.use((req, res, next) => {
    res.setHeader(
        'Content-Security-Policy-Report-Only',
        "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'"
    );
    next();
});

Cloudflare Transform Rule

In the Cloudflare dashboard: Rules → Transform Rules → Modify Response Header → Create rule. Add a "Set static" action:

Header name: Content-Security-Policy-Report-Only
Value: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'

Transform Rules are available on the Free plan (limited quota). For higher volume use a Cloudflare Worker instead. → Full guide: CSP on Cloudflare — covers Set vs. Add, Email Obfuscation and Rocket Loader caveats, and the Worker pattern for nonces.

vercel.json

Add a headers entry to your project's vercel.json:

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Content-Security-Policy-Report-Only",
          "value": "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'"
        }
      ]
    }
  ]
}

Redeploy after committing — headers are applied at the edge.

Get a CSP tailored to your site → Free scan · covers every resource your site actually loads · copy-paste snippets for all platforms above

Why the generic example isn't enough

The policy above uses default-src 'self', which blocks everything that doesn't come from your own origin. Real websites load Google Fonts, analytics, embedded videos, maps, chat widgets and so on — each of which needs to be whitelisted explicitly. Guessing wrong breaks the site, and a too-permissive policy defeats the whole point of CSP.

That's why a one-size-fits-all CSP doesn't work. Our scanner crawls your site, finds every external resource it actually loads, and generates the tightest possible policy that still keeps everything working — plus the copy-paste deployment snippet for your stack.