CSP Explained: A Practical Guide to Content Security Policy

CSP explained clearly: what Content Security Policy is, which directives matter, how to deploy it safely, and how to monitor it so it never silently breaks.

CSP Explained: A Practical Guide to Content Security Policy

By Krithi

If you've ever opened your browser's developer console and seen a wall of Content-Security-Policy violations, or inherited a codebase where someone just set default-src * and called it a day, you already know the problem. Content Security Policy is one of the most powerful browser security mechanisms available — and one of the most routinely misunderstood. This guide cuts through the noise and gives you a clear, working understanding of what CSP does, how to write a sensible policy, and how to keep it healthy over time.


What Is Content Security Policy?

Content Security Policy (CSP) is an HTTP response header that tells the browser which sources of content — scripts, stylesheets, images, fonts, frames, and more — are allowed to load on a given page. Any resource that doesn't match the policy is blocked before it can execute or render.

The core idea is straightforward: instead of relying solely on the server to serve clean content, you explicitly whitelist what's permitted. This creates a strong second line of defence against cross-site scripting (XSS), clickjacking, mixed-content injection, and data exfiltration attacks.

CSP is delivered as a response header:

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

Or, during development and rollout, as a report-only header that logs violations without blocking anything:

` Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-reports `

The browser interprets the header, enforces (or observes) the policy, and — if you've set up a reporting endpoint — sends JSON violation reports whenever something is blocked.


Why CSP Matters for Real-World Security

XSS remains one of the most common web vulnerabilities. An attacker who finds a way to inject arbitrary HTML or JavaScript into your page can steal session cookies, capture form inputs, redirect users, or silently beacon data to an external server.

A well-crafted CSP doesn't eliminate XSS bugs in your code, but it severely limits what an attacker can do with them. Even if malicious JavaScript is injected, the browser won't execute it if the script source isn't explicitly permitted. That's a meaningful reduction in blast radius.

Beyond XSS, CSP also:

  • Blocks mixed content — prevents HTTP resources from loading on HTTPS pages, protecting transport-layer security.
  • Prevents clickjacking — the frame-ancestors directive replaces the older X-Frame-Options header and gives you more granular control.
  • Limits data exfiltrationconnect-src restricts where JavaScript can send data via fetch, XMLHttpRequest, and WebSockets.

!Diagram showing how a browser enforces CSP directives to block unauthorised scripts and connections


CSP Directives You Actually Need to Know

The CSP specification has dozens of directives, but most policies rely on a manageable subset.

Fetch Directives

These control where resources can be loaded from:

| Directive | Controls | |---|---| | default-src | Fallback for all resource types not explicitly listed | | script-src | JavaScript, including inline scripts and eval() | | style-src | Stylesheets and inline styles | | img-src | Images and favicons | | font-src | Web fonts | | connect-src | Fetch, XHR, WebSocket, EventSource | | frame-src |