Content Security Policy
In short
A Content Security Policy is an HTTP response header that tells the browser which scripts, styles, and other resources a page may load, blocking injected code.
What is a Content Security Policy?
A Content Security Policy, or CSP, is a set of rules a website sends in the Content-Security-Policy HTTP header. Each rule, called a directive, lists the allowed sources for one type of resource, such as script-src for JavaScript, style-src for CSS, img-src for images, and connect-src for fetch() and WebSocket connections. The browser enforces the rules and blocks anything that does not match.
CSP is mainly a second line of defense against cross-site scripting (XSS). If an attacker manages to inject a <script> tag or an inline event handler into a page, a strict policy stops the browser from running it, because the script does not come from an allowed source. The recommended approach is a strict policy based on nonces or hashes: the server generates a fresh random nonce for each response and adds it to the header and to each legitimate <script> tag, so only those scripts run.
Think of CSP as a guest list for your page: even if an intruder sneaks in through a bug, the bouncer only lets in scripts whose names are on the list. CSP can also block clickjacking with the frame-ancestors directive, which controls which sites may embed your page in an iframe, and upgrade insecure resource requests to HTTPS with upgrade-insecure-requests.
CSP does not replace fixing XSS bugs with output encoding and sanitization; it limits the damage when a bug slips through. Common mistakes are adding 'unsafe-inline' or broad sources like https: to script-src, which cancel most of the protection. Roll out a new policy with the Content-Security-Policy-Report-Only header first, review the violation reports, and switch to enforcement once legitimate resources are no longer blocked.
Key takeaways
- CSP is an HTTP header that restricts where a page can load resources from.
- Its main purpose is to block injected scripts and reduce XSS damage.
- Strict policies use nonces or hashes instead of long domain allowlists.
frame-ancestorsprotects against clickjacking.- Test with
Content-Security-Policy-Report-Onlybefore enforcing.
Example
# Only scripts carrying this response's nonce may run
# (the server generates a new random nonce for every response)
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Security-Policy: script-src 'nonce-r4nd0mV4lue' 'strict-dynamic'; object-src 'none'; base-uri 'none'; frame-ancestors 'self'
<!-- Allowed: the nonce matches the header -->
<script nonce="r4nd0mV4lue" src="/app.js"></script>
<!-- Blocked: an injected script has no valid nonce -->
<script>stealCookies()</script>Readers ask
Does a Content Security Policy prevent XSS?
A strict CSP blocks most ways injected scripts can run, which greatly reduces the impact of XSS, but it is a backup layer rather than a cure. You still need to encode output and sanitize any user-supplied HTML.
What is a CSP nonce?
A nonce is a random value, generated fresh for every response, that is placed in the CSP header and on each trusted <script> tag. The browser runs only scripts with a matching nonce, and an attacker cannot guess it in advance.
What does unsafe-inline mean in CSP?
'unsafe-inline' allows inline scripts and event handler attributes such as onclick to run, which is exactly what most XSS attacks inject. Avoid it in script-src and use nonces or hashes instead.
See also
- XSSSecurity, p. 48XSS is a vulnerability that lets an attacker inject malicious JavaScript into a trusted website so that it runs in other users' browsers.
- HTTPWeb Development, p. 19HTTP is the protocol that browsers, apps, and servers use to exchange web pages and data through a simple cycle of requests and responses.
- HTTPSSecurity, p. 17HTTPS is the secure version of HTTP that encrypts traffic between a browser and a website with TLS, protecting data from eavesdropping and tampering.
- JavaScriptWeb Development, p. 24JavaScript is the programming language that runs in web browsers to make pages interactive, and it also runs on servers through runtimes like Node.js.
- HTMLWeb Development, p. 18HTML is the markup language that defines the structure and content of web pages, such as headings, paragraphs, links, images, and forms.
- CORSWeb Development, p. 8CORS is a browser security mechanism that lets a server declare which other websites may read its responses when they make requests from JavaScript.
Spotted a mistake or something missing on this page?Suggest an edit