Medium SeveritySecurity Headers

Fix: Content-Security-Policy Not Set

Your server does not send a Content-Security-Policy (CSP) header. CSP is one of the most effective defenses against cross-site scripting (XSS) and data injection attacks.

Quick Fix

Add a Content-Security-Policy header starting with a report-only policy, then enforce.

What This Error Means

Content-Security-Policy tells browsers which sources of content (scripts, styles, images) are allowed to load on your pages. Without it, browsers allow content from any source, making XSS attacks easier.

Why It Matters

CSP is one of the strongest browser-side defenses against XSS. It prevents inline script injection, restricts content sources, and blocks mixed content. Recommended by OWASP and required by many compliance frameworks.

Step-by-Step Fix

1

Start with Content-Security-Policy-Report-Only

Deploy in report-only mode first to log violations without blocking anything.

Example
# Nginx:
add_header Content-Security-Policy-Report-Only "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; report-uri /csp-report" always;
2

Review violations

Monitor CSP violation reports. Each violation shows a resource that would be blocked. Add legitimate sources to your policy.

3

Refine the policy

Add necessary sources for third-party scripts, styles, fonts, and images.

Example
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' https://js.stripe.com https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; img-src 'self' data: https:; connect-src 'self' https://api.stripe.com; frame-src https://js.stripe.com https://challenges.cloudflare.com
4

Switch to enforcement

Once confident the policy does not block legitimate resources, switch from report-only to enforcing.

Before
add_header Content-Security-Policy-Report-Only "default-src 'self'; ..." always;
After
add_header Content-Security-Policy "default-src 'self'; ..." always;
5

Verify the policy

Check that the CSP header is present and working.

Example
curl -sI https://yourdomain.com | grep -i content-security-policy

Common Gotchas

  • A CSP that is too restrictive will break your site. Always start with report-only mode.
  • Inline scripts and styles are blocked by default in CSP. You need 'unsafe-inline' (less secure) or nonces/hashes.
  • Third-party widgets, analytics, and ad scripts often load from many domains. You may need to whitelist several.

Verify Your Fix

After making changes, use our free scanner to verify the fix is working correctly. DNS changes can take up to 48 hours to propagate, but most propagate within minutes.

Frequently Asked Questions

What is the minimum useful CSP?

A basic starting point: Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:;

What does unsafe-inline mean in CSP?

'unsafe-inline' allows inline scripts or styles, weakening XSS protection. More secure alternatives are nonces (script-src 'nonce-random123') or hashes of specific inline scripts.

How do I handle CSP with a single-page application?

SPAs often need 'unsafe-inline' for styles and careful whitelisting of API endpoints in connect-src. Use nonces for inline scripts. Most frameworks (React, Next.js) can be configured for strict CSP.

Related Issues