What Is Content Security Policy (CSP)?
Content Security Policy is a browser security control delivered primarily through an HTTP response header. It tells the browser which sources may load scripts, styles, images, fonts, frames, and network connections, reducing the impact of cross-site scripting and other content-injection attacks.
What CSP helps protect against
A well-designed CSP can restrict unauthorized script execution, unexpected framing or embedded content, unapproved network destinations, and other browser resource loads. It can also upgrade insecure requests. CSP is especially valuable for reducing the impact of some XSS and injected-content vulnerabilities.
What CSP does not replace
CSP does not make vulnerable code safe and does not replace output encoding, input handling, sanitization, dependency security, authentication controls, or application testing. Treat it as an additional browser-enforced layer.
How Content Security Policy works
The browser receives a policy as a set of directives. Each directive governs a resource type or browser behavior. A source list then identifies allowed origins, schemes, nonces, hashes, or keywords for that directive.
If a page tries to load or execute something that the enforced policy does not allow, the browser blocks it. In report-only mode, the browser reports the violation without applying the block, which lets teams observe expected and unexpected behavior before enforcement.
A small CSP header example
Content-Security-Policy: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none';
This example is a teaching aid, not a drop-in production policy. Real applications usually need explicit directives for their scripts, styles, images, fonts, frames, forms, and connections.
Compact CSP directive glossary
These are the directives most often involved when you create a CSP, validate a generated policy, or read browser violation reports.
default-src
Fallback policy for resource types that do not have a more specific directive.
script-src
Controls JavaScript sources, inline script hashes, nonces, and risky values like 'unsafe-eval'.
style-src
Controls stylesheets and inline style allowances, including hashes or nonces when used.
img-src
Controls image sources, including common allowances such as same-origin CDNs or carefully reviewed data: images.
connect-src
Controls fetch, XHR, WebSocket, EventSource, and API endpoints.
font-src
Controls web font sources such as local assets, Google Fonts, or a private asset CDN.
frame-src
Controls iframes and embedded content loaded by your page.
frame-ancestors
Controls which parent pages may embed your page and helps prevent clickjacking.
object-src
Controls legacy plugin content. Most modern policies set this to 'none'.
base-uri
Restricts which URLs can be used in a document <base> element.
form-action
Controls where forms can submit data.
report-to
Names a Reporting API endpoint for CSP violation reports.
Report-only CSP versus enforced CSP
Content-Security-Policy-Report-Only observes violations without blocking them. Use it while exercising representative public, authenticated, interactive, consent-gated, and conditional application flows.
Content-Security-Policy enforces the rules and can break functionality when a required source or behavior is missing. Move to enforcement only after reviewing reports, removing unnecessary allowances, and confirming the policy across the flows that matter to the application.
See the Report-Only CSP Testing Guide for headers, reporting directives, and violation examples.
How CSP nonces and hashes work
A nonce is an unpredictable value generated for each HTTP response and applied to both the policy and the intended inline script or style element. A source hash authorizes inline content whose exact bytes match the hash in the policy.
CSP supports SHA-256, SHA-384, and SHA-512 source hashes. Script Sentinel's optional scanner hashing currently emits SHA-256 sources for non-empty inline content observed on scanned pages. Because hashes are content-sensitive, they must be regenerated when the inline content changes. Script Sentinel does not create or inject per-response nonces.
How to create and deploy a CSP
- Inventory resources. Identify the scripts, styles, images, fonts, frames, APIs, and other destinations the application actually needs.
- Build a candidate. Start with narrowly scoped directives and defense directives such as
object-src,base-uri, andframe-ancestors. - Review trust. Do not assume an observed third-party source is safe simply because the page loaded it.
- Test report-only. Exercise representative user flows and collect violations without blocking functionality.
- Refine the policy. Add genuinely required behavior, remove unused sources, and avoid broad allowances where practical.
- Enforce and monitor. Deploy the enforced header after review, then watch for application changes and CSP drift.
Common CSP mistakes
- Using
*, broad schemes, or wide subdomain wildcards without reviewing the trust they grant. - Depending on
'unsafe-inline'or'unsafe-eval'when a nonce-, hash-, or code-refactoring strategy is feasible. - Copying a generic CSP example directly into production without matching it to the application.
- Enforcing before testing authenticated, interactive, and conditional flows.
- Treating a CSP scanner as proof that every application state or third party is safe.
- Deploying a policy once and never reviewing it as the site changes.
Browser support and further reading
Modern browsers broadly support CSP, but individual directives and reporting features differ. Check current compatibility for the directives you plan to use.
Content Security Policy FAQ
Is CSP an HTTP header or a meta tag?
The HTTP response header is the recommended delivery method and supports the complete policy at response time. A CSP meta element supports a more limited policy and cannot replace every header capability.
Does CSP prevent every XSS vulnerability?
No. CSP can restrict what injected content may load or execute, but it does not fix the vulnerable code and can be weakened by broad source expressions.
What is report-only mode?
Report-only mode records policy violations without blocking them, allowing teams to find missing sources and unexpected behavior before enforcement.
Can I deploy a generated CSP directly?
Use generated output as a candidate. Review its sources, test representative flows in report-only mode, and have an application owner approve the enforced policy.
Build a CSP from observed browser evidence
Scan selected public pages, inspect the candidate, and begin report-only testing.