A Content Security Policy is an HTTP header that tells the browser which sources of script, style, and other content it is allowed to load and execute — in short, the CSP meaning in security is a browser-enforced allowlist for executable content, not a scanner or a firewall rule. Its primary job is to contain cross-site scripting: even if an attacker manages to inject markup into your page, a well-built CSP stops the injected script from running. That makes CSP a genuine last line of defense, the control that turns a would-be account takeover into a blocked, reported non-event. It is also one of the most misconfigured headers on the web, because the easy way to write a CSP, an allowlist of trusted hosts, is the way that attackers routinely bypass.
The short answer for 2026: deploy a strict, nonce-based CSP with strict-dynamic, avoid unsafe-inline and host allowlists, roll it out first in report-only mode, and add Trusted Types to close off DOM-based XSS. Here is how each piece fits.
How CSP works
The browser reads the Content-Security-Policy header and enforces its directives against every resource the page tries to load. Each directive names a resource type and the sources permitted for it. The classic (and weak) approach lists allowed hosts:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'
The problem with host allowlists is that any allowed host with an open redirect, a JSONP endpoint, or an outdated library becomes a bypass. Research repeatedly shows the majority of allowlist-based policies are trivially bypassable. The modern recommendation is a strict, nonce-based policy instead.
Strict, nonce-based CSP
With a nonce, the server generates a fresh random value per response and stamps it on every script tag it trusts. The browser runs only scripts carrying the correct nonce, so injected script (which cannot know the nonce) never executes. Adding strict-dynamic lets your trusted scripts load further scripts they need, so you do not have to allowlist every CDN.
Content-Security-Policy:
script-src 'nonce-r4nd0m123' 'strict-dynamic';
object-src 'none';
base-uri 'none';
require-trusted-types-for 'script'
The matching markup carries the nonce (note: this is illustrative, and the nonce is regenerated per request):
<script nonce="r4nd0m123" src="/app.js"></script>
Three details make or break a strict CSP. First, the nonce must be unguessable and unique per response; a static or reused nonce is worthless. Second, object-src 'none' and base-uri 'none' close off plugin and base-tag injection vectors that attackers use to sidestep script controls. Third, never add 'unsafe-inline' to script-src; when a nonce is present modern browsers ignore 'unsafe-inline' anyway, but adding it out of habit signals a policy that was copied rather than designed.
Roll out in report-only mode
Do not enforce a new CSP blind. Ship it first as report-only, which reports violations without blocking anything, so you can see what real traffic would break before it does.
Content-Security-Policy-Report-Only:
script-src 'nonce-r4nd0m123' 'strict-dynamic';
object-src 'none';
report-to csp-endpoint
Collect reports for a representative period, fix the legitimate sources that trip the policy (usually inline handlers and third-party widgets), then switch the header to enforcing. Keep a reporting endpoint even after enforcement so you get an early signal when an injection attempt or a broken deploy occurs.
Close DOM XSS with Trusted Types
CSP historically controlled where scripts came from, not the dangerous DOM sinks like innerHTML that cause DOM-based XSS. Trusted Types, enabled with require-trusted-types-for 'script', forces those sinks to receive a typed, sanitized value instead of a raw string, eliminating a whole category of client-side injection at the browser level.
CSP checklist
| Do | Avoid |
|---|---|
Use per-response nonces with strict-dynamic | Host allowlists as your primary control |
Set object-src 'none' and base-uri 'none' | Adding 'unsafe-inline' to script-src |
| Roll out with report-only first | Enforcing a brand-new policy blind |
| Keep a live reporting endpoint | Disabling reporting after go-live |
| Add Trusted Types for DOM sinks | Assuming CSP alone stops DOM XSS |
How Safeguard helps
A CSP is a runtime property of your deployed pages, so it is best verified from the outside. Safeguard's dynamic application security testing inspects your live responses, flags a missing, weak, or bypassable CSP, and correlates it with the injection findings the policy is meant to contain. Griffin AI explains why a given policy is weak and drafts a strict replacement tailored to the sources your app actually uses, while the Safeguard CLI lets you assert CSP presence against preview builds in CI. Because injected code often rides in through vulnerable front-end packages, Safeguard also runs software composition analysis on your dependency graph, and teams comparing tools can review the pricing.
Ship a CSP that actually holds: get started free or read the documentation.
Frequently Asked Questions
What does a Content Security Policy actually protect against?
Primarily cross-site scripting. A strict CSP tells the browser which scripts are allowed to execute, so even if an attacker injects markup into your page, the injected script lacks the correct nonce and never runs. It also mitigates clickjacking (via frame-ancestors), plugin injection, and base-tag attacks.
Why is a nonce-based CSP better than an allowlist of hosts?
Host allowlists are routinely bypassed: any allowlisted domain with an open redirect, a JSONP endpoint, or a vulnerable script becomes an execution path for injected code. A per-response nonce with strict-dynamic trusts specific script instances rather than whole domains, which removes those bypasses.
How do I deploy CSP without breaking my site?
Start with Content-Security-Policy-Report-Only, which reports violations without blocking. Collect reports across real traffic, fix the legitimate sources that trip the policy, then switch to the enforcing Content-Security-Policy header. Keep a reporting endpoint afterward for early warning of injection attempts and broken deploys.
Does CSP stop DOM-based XSS?
Not by itself, because classic CSP governs where scripts load from, not dangerous DOM sinks like innerHTML. Add require-trusted-types-for 'script' to enable Trusted Types, which forces those sinks to accept only sanitized typed values and eliminates a major class of client-side injection.
What is the CSP meaning in security terms?
In a security context, CSP is short for Content Security Policy — a browser-enforced allowlist, delivered as an HTTP response header, that restricts which script, style, and other resource sources a page is permitted to load and execute. It exists specifically to contain cross-site scripting after an injection has already happened, not to prevent the injection itself.