CORUZEN
Back to blog

What is CSP (Content Security Policy) and how to set it up

By CORUZEN Team · Jul 28, 2026 · 4 min read

What is CSP (Content Security Policy) and how to set it up

If you've ever run a security scan on your site, chances are you've run into an item called Content Security Policy — CSP for short. It's one of the most common findings in security reports, and also one of the most postponed: it sounds complicated, it sounds risky, and "the site already works, why touch it."

The thing is, CSP solves a real problem, and solves it well. It's worth understanding what it actually does before deciding whether it's worth implementing (spoiler: it is).

What it actually does

Content Security Policy is an HTTP header your server sends with every page, telling the browser where it's allowed to load things from: scripts, images, fonts, styles, iframes. Anything not on that list, the browser refuses to load — even if malicious code has already been injected into the page somehow.

That's the distinction that matters: CSP doesn't stop someone from injecting a malicious script into your HTML in the first place (that's input validation and sanitization's job). What it does is guarantee that even if the injection happens, the browser refuses to execute that script, because it didn't come from an authorized origin.

Which attacks a CSP mitigates

  • XSS (Cross-Site Scripting) — the main one. If an attacker manages to inject a malicious <script> into a comment field, a URL, or any input that ends up rendered unescaped, a well-configured CSP blocks that script from running.
  • Clickjacking — through the frame-ancestors directive, which prevents your site from being loaded inside an invisible <iframe> on another page, a technique used to trick users into clicking things they didn't mean to.
  • Data injection — restricts where forms can submit data (form-action) and where the site can load resources from, making data exfiltration through injected scripts harder.
  • Base tag attacks — the base-uri directive prevents an attacker from rewriting the page's base URL to redirect relative resources to a malicious domain.

The directives that matter most

A CSP is a list of directives, each controlling one type of resource:

DirectiveWhat it controls
default-srcDefault origin for anything without its own directive
script-srcWhere scripts can be loaded/executed from
style-srcWhere stylesheets (CSS) can come from
img-srcWhere images can be loaded from
connect-srcWhere the site can make requests to (fetch, XHR, WebSocket)
object-srcPlugins like <object>, <embed> — almost always 'none'
frame-ancestorsWho can put your site inside an <iframe>
base-uriWhat values the <base> tag is allowed to take

A reasonable minimal policy for most corporate sites restricts everything to 'self' (the site's own domain) and explicitly denies what shouldn't exist:

default-src 'self';
object-src 'none';
frame-ancestors 'self';
base-uri 'self';

Why so many teams avoid implementing it

The most common fear is a fair one: a misconfigured CSP breaks the site — blocks an analytics script, an external font, a third-party widget — and nobody notices until a customer complains. That's exactly why report-only mode exists: you publish the policy without it actually blocking anything, and it only reports what would have been blocked. That gives real visibility into which origins your site actually uses, before enforcing the policy for real.

The safe path, in short:

  1. Map the external resources the site actually loads (analytics, fonts, CDNs, widgets).
  2. Start in report-only, let it run for a few days while monitoring violation reports.
  3. Adjust the directives based on what shows up — usually a much shorter list than you'd expect.
  4. Enforce it for real, first in staging, then in production.
  5. Re-run a security scan to confirm the policy is present and properly structured.

Common mistakes

  • Using 'unsafe-inline' without needing to — this allows any inline script, which undoes most of the XSS protection. It should only be there if the site genuinely depends on dynamic inline scripts (some server-rendered frameworks occasionally need it, but it's always worth evaluating case by case).
  • Forgetting object-src 'none' — even sites that don't use Flash or plugins leave this directive out, opening an unnecessary door.
  • Copying the CSP from another site — every site loads different resources. A policy copied from another project tends to be either too permissive (protects nothing) or too restrictive (breaks functionality).
  • Set it and forget it — CSP needs to keep up with changes to the site. Added a new third-party widget? The policy needs to know about it.

The practical outcome

A site with a well-configured CSP isn't "slower" or "harder to maintain" — the header is just one line of server configuration. What changes is that, if an injection vulnerability ever slips through somewhere else in the system, CSP is the layer that stops it from becoming a real attack against whoever visits the site.

That's the kind of control — along with other security headers, properly configured DNS, and no exposed secrets — that makes up a site's security score. If you want to know exactly where your site stands today, without guesswork, you can run a full scan and get a prioritized remediation plan.

Want to see this in practice?

Check out CORUZEN SECURITY and see how it solves this in your company's day to day.

Explore CORUZEN SECURITY