In web security, CSP means Content Security Policy, a browser-enforced allowlist delivered as an HTTP response header that tells the browser which origins the page is permitted to load scripts, styles, images, and other resources from, and just as importantly, which to refuse. Understanding the CSP meaning in security matters because it is one of the few defenses that limits the damage of a cross-site scripting flaw even after an attacker has managed to inject markup. It does not fix the injection; it takes away much of what the injected code can do.
If you have only ever seen Content-Security-Policy as a header your framework sets, this is the plain-language version of what it is for and how to write one that helps rather than one that breaks your site.
What the policy actually controls
A CSP is a set of directives, each naming a resource type and the sources allowed for it. The browser reads the header on every response and enforces the rules as it builds the page. If the page tries to load something outside the policy, the browser blocks it and, if you have asked it to, reports the violation.
A minimal but meaningful policy might read:
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'; base-uri 'self'; frame-ancestors 'none'
Here default-src 'self' sets the fallback to same-origin only, script-src additionally permits one trusted CDN, object-src 'none' kills legacy plugin vectors, base-uri 'self' stops an injected base tag from rewriting relative URLs, and frame-ancestors 'none' prevents the page from being framed, which is a clickjacking defense.
Why CSP blunts XSS
Cross-site scripting works by getting the browser to execute attacker-controlled script in the context of your origin. A well-built CSP breaks the most common ways that script runs. If your policy does not include 'unsafe-inline' in script-src, the browser refuses to run inline <script> blocks and inline event handlers, which is where reflected and stored XSS payloads usually land. If it does not include 'unsafe-eval', eval and its relatives stop working, closing another execution path.
The key insight in the CSP meaning for security is layering. Output encoding and input validation aim to stop injection from happening. CSP assumes one of those will eventually fail and limits what the injected code can accomplish. Defense in depth, not a single wall.
Nonces and hashes over unsafe-inline
The hard part of a real CSP is legitimate inline scripts. The lazy fix is 'unsafe-inline', which disables the very protection you added the policy for. The right fix is a nonce or a hash.
A nonce is a random value generated per response, placed on the header and on each trusted inline script:
Content-Security-Policy: script-src 'nonce-r4nd0mPerRequest' 'strict-dynamic'
<script nonce="r4nd0mPerRequest">/* trusted inline code */</script>
The browser runs only inline scripts carrying the matching nonce, so an injected script without it is blocked. Generate a fresh nonce every request; a static one is worthless. 'strict-dynamic' lets a trusted script load further scripts it needs, which keeps modern bundlers working without opening the whole origin.
Roll it out without breaking the site
The fastest way to break production is to ship a strict CSP blind. Use the report-only mode first. The Content-Security-Policy-Report-Only header enforces nothing but sends a violation report to an endpoint you specify, so you can see what a real policy would have blocked using genuine traffic:
Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-reports
Watch the reports, add the sources you legitimately use, and only then switch to the enforcing header. Expect third-party scripts, analytics, and embeds to surface here; each is a source you must decide to trust or drop.
CSP is not a standalone fix
Treat CSP as one control among several. It does nothing against server-side injection, does not protect users on browsers that ignore parts of the spec, and a policy weakened by 'unsafe-inline' or an overly broad wildcard gives thin protection. Keep encoding output, validating input, and setting HttpOnly on session cookies, the cookie discipline covered in our guide to secure session management.
Because a permissive CSP often creeps in through third-party front-end dependencies that demand inline scripts, watching what your build pulls in matters too; our software composition analysis coverage explains where those requirements hide. A DAST scan can also flag a missing or weak CSP header from the outside.
FAQ
What does CSP stand for in security?
CSP stands for Content Security Policy. It is an HTTP response header that tells the browser which sources of scripts, styles, and other content the page is allowed to load, and blocks anything outside that allowlist.
Does CSP prevent XSS entirely?
No. CSP limits what injected script can do rather than preventing the injection itself. A strong policy without 'unsafe-inline' blocks the most common execution paths, but you still need output encoding and input validation as primary defenses.
What is the difference between CSP and CSP-Report-Only?
The enforcing Content-Security-Policy header blocks violations. The Content-Security-Policy-Report-Only header blocks nothing but reports what would have been blocked, which lets you tune a policy safely before enforcing it.
Should I use a nonce or unsafe-inline for inline scripts?
Use a per-request nonce or a hash. 'unsafe-inline' disables the protection CSP exists to provide, so it defeats the purpose. A nonce lets your trusted inline scripts run while still blocking injected ones.