What is a Content Security Policy (CSP)?
A Content Security Policy is an HTTP header that tells browsers which resources a page may load. Learn how CSP blocks XSS attacks and how to deploy one safely.
A Content Security Policy (CSP) is an HTTP response header that tells the browser which sources a page may load content from: scripts, styles, images, frames, fonts. Anything that violates the policy gets blocked, and the browser can send you a report about it.
Why CSP matters
Cross-site scripting (XSS) remains one of the most common web vulnerabilities, and no amount of careful input handling makes it disappear entirely. One injection flaw is enough for an attacker to run arbitrary JavaScript in your users’ browsers. A well-built CSP gives you a second line of defense. The injected code may well land in the page, but the browser refuses to execute it because its source is not allowed by the policy.
A minimal example
Content-Security-Policy: default-src 'self'; script-src 'self' https://js.example.com; object-src 'none'; base-uri 'self'
Broken down:
- everything loads from the page’s own origin by default (
default-src 'self'). - scripts are allowed only from the origin and
https://js.example.com. - plugins are forbidden outright (
object-src 'none'). base-uri 'self'prevents<base>tag hijacking, an attack most people forget exists.
Report-only first, enforce later
Ship a strict policy straight to production and something will break. Usually an inline script you forgot about, a third-party widget, or a browser extension doing something odd. The safe path:
- Ship the policy with the
Content-Security-Policy-Report-Onlyheader. Nothing is blocked yet. - Point
report-uri/report-toat a violation collection endpoint. - Review the reports. Fix the legitimate violations, filter out the extension noise.
- Switch the header to
Content-Security-Policyto enforce it.
The reports are the painful part: high volume, mostly noise. That is why teams use a dedicated platform such as CentralCSP to aggregate reports, separate real issues from browser-extension junk, and track policy changes over time.
Key directives at a glance
| Directive | Controls |
|---|---|
default-src | Fallback for all resource types |
script-src | JavaScript sources, inline scripts, eval |
style-src | Stylesheets and inline styles |
img-src | Images and favicons |
connect-src | fetch, XHR, WebSocket targets |
frame-ancestors | Who may embed this page (clickjacking protection) |
report-to / report-uri | Where violation reports are sent |
Where to go next
Start in report-only mode, collect a week of real traffic, then iterate. The next decision waiting for you is nonces or hashes, and it turns on your caching setup more than on your threat model. If what you are protecting is a logged-in product rather than a marketing site, CSP for SaaS platforms picks the story up there. And if nobody on the team has security in their job title, running a solid CSP without a dedicated security engineer is the version we wrote for you.
Frequently asked questions
Does a CSP replace input sanitization?
No. CSP is a defense-in-depth layer. You should still sanitize and escape user input. CSP limits the damage when a cross-site scripting vulnerability slips through anyway.
Will enabling CSP break my site?
It can if deployed carelessly. Start with Content-Security-Policy-Report-Only mode, collect violation reports with a tool like CentralCSP, then enforce the policy once the reports come back clean.
What is the difference between report-only and enforced CSP?
Report-only mode sends violation reports without blocking anything, which makes it safe for testing. Enforced mode blocks disallowed resources and sends reports as well.