Content-Security-Policy (CSP) Header Explained

Jul 16, 2026
Updated Jul 16, 2026 Security Headers content-security-policy csp header content security policy header csp xss

The Content-Security-Policy (CSP) HTTP response header tells the browser which sources of content — scripts, styles, images, fonts, and more — are allowed to load and run on a page. It is the single most effective header for defending against cross-site scripting (XSS) and other content-injection attacks, because even if an attacker manages to inject a script, the browser refuses to execute it unless CSP explicitly allows its source.

What is the Content-Security-Policy header?

Defined by the W3C CSP specification, the header works as an allowlist. You declare, per resource type, which origins the browser may load from. Anything not on the list is blocked. Because the enforcement happens in the browser, CSP turns a successful injection into a non-event: the malicious <script> loads from an origin the policy never approved, so it never runs.

How CSP works: directives

A policy is a set of directives, each controlling one resource type:

DirectiveControls
default-srcThe fallback source list for any directive not set explicitly.
script-srcWhere JavaScript may load from — the key XSS control.
style-srcWhere CSS may load from.
img-srcWhere images may load from.
connect-srcEndpoints for fetch/XHR/WebSocket.
frame-ancestorsWho may embed this page in a frame — the modern anti-clickjacking control.
object-srcPlugins such as Flash; usually set to 'none'.

Common source values are 'self' (the page's own origin), 'none' (block everything), a specific host like https://cdn.example.com, and — for inline scripts you cannot remove — a 'nonce-…' or 'sha256-…' hash.

Example CSP header

Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'; frame-ancestors 'self'

This allows scripts only from the site itself and one trusted CDN, blocks plugins entirely, and lets only the same origin frame the page.

How to check your CSP

To see whether a site sends a Content-Security-Policy header and what it contains, run it through the free HTTP headers checker, or review all of a site's protections at once with the security headers guide.

When rolling out a policy, deploy it first in report-only mode with the Content-Security-Policy-Report-Only header, which logs violations without blocking anything, so you can tune the policy before enforcing it.

Common CSP mistakes

  • Using 'unsafe-inline' in script-src. This allows any inline script to run and defeats most of CSP's XSS protection. Use nonces or hashes instead.
  • Wildcards that are too broad. script-src * or a blanket https: allows almost anything and provides little protection.
  • Forgetting frame-ancestors. Without it, CSP does not stop clickjacking; pair it with, or replace, X-Frame-Options.

Related security headers

CSP is the centrepiece of a headers strategy but works alongside others: X-Frame-Options (legacy clickjacking defence), X-Content-Type-Options (MIME-sniffing), and HSTS (force HTTPS).

Frequently asked questions

Does CSP stop all XSS?

No single control does, but a strict CSP without 'unsafe-inline' blocks the large majority of XSS payloads from executing, making it the most valuable header for XSS defence.

What is the difference between CSP and X-Frame-Options?

CSP's frame-ancestors directive is the modern, more flexible way to control who can frame your page. X-Frame-Options does only that one job and remains for older browsers.

How do I test a CSP without breaking my site?

Send it with the Content-Security-Policy-Report-Only header first. The browser reports what the policy would block without actually blocking it, so you can fix legitimate sources before enforcing.

Scan for these vulnerabilities

Secably automatically detects the issues discussed in this article.

Start Free Scan