Content Security Policy: A Deployable Defense in Depth
Content Security Policy lets a server restrict which resources a document may load and which execution patterns it permits.
- Author
- absequ
- Published
- Updated
- Category
- Security
- content security policy
- security
- practical guide
Content Security Policy lets a server restrict which resources a document may load and which execution patterns it permits. It is a browser-enforced mitigation that can reduce the impact of some injection mistakes. It does not sanitize input, authorize requests or repair unsafe application logic. A useful policy is designed around real resource needs and tested incrementally.
On this page
The mental model
The browser applies directives to categories such as scripts, styles, images and network connections. A resource allowed by one category is not automatically allowed by another. For example, loading a script and allowing that script to connect to an analytics endpoint are separate decisions. Understand the fallback rules before treating default-src as a complete policy.
Nonces and hashes can authorize particular script content without allowing arbitrary inline execution. Generate a fresh unpredictable nonce for each applicable response and ensure the HTML and header agree. A hardcoded reusable nonce is not an effective nonce strategy. Framework-generated scripts need explicit integration rather than ad hoc header edits.
A practical workflow
Inventory necessary first-party and third-party resources, including dynamically loaded assets and form/CAPTCHA behavior. Start with a report-only policy in a controlled rollout to observe violations without immediately blocking users. Investigate each report: extensions and injected browser tooling can generate noise, while a genuine violation may reveal an undocumented dependency.
The illustrative header below is intentionally minimal and is not a drop-in configuration for Next.js. Framework bootstrapping, inline styles, development tooling and approved integrations need a separately validated policy. Keep development allowances out of production rather than making a permissive policy permanent to get a build working.
Worked example
Content-Security-Policy-Report-Only:
default-src 'self';
script-src 'self' 'nonce-RESPONSE_SPECIFIC_RANDOM_VALUE';
object-src 'none';
base-uri 'self';
frame-ancestors 'none'
# Replace the nonce placeholder per response and apply it to approved scripts.
# This multiline representation explains directives; emit a valid header value.Report-only delivery and enforced delivery are different headers. Once an enforced policy is enabled, blocked resources can change real functionality. Test sign-in, forms, media, navigation and hydration in a production-like browser session, not just a static response inspection. If multiple enforced policies are delivered, they do not simply merge into a more permissive union.
Use narrow source lists and remove allowances that no longer have a consumer. An analytics integration should not justify broad wildcards for unrelated script origins. Keep a documented reason for each source and validate redirects and subresources used by a provider. Policy maintenance is part of integration maintenance.
Failure modes and security
Unsafe inline script allowances and broad evaluation permissions weaken the boundary. A policy can also leak sensitive URLs through reports, so treat a report collector as untrusted input and protect access to stored reports. Limit payload size and retention, redact secrets and avoid exposing a public report dashboard.
A successful CSP deployment does not make HTML injection safe. Continue using context-appropriate output handling and avoid executing strings as code. For browser support and directive semantics, consult the current documentation and verify the behavior in the browsers your product actually supports.
Practice and verification
Build a resource inventory for a small local page and explain every allowed origin. Introduce one controlled disallowed resource and verify the report-only signal. Then enforce the policy in staging and verify that useful functionality still works. Record the exact headers and browser console evidence. Do not weaken the policy merely to silence every report; distinguish a necessary application resource from an extension or an unexpected dependency.
References
MDN CSP guide — MDN
OWASP CSP guidance — OWASP