Security· Intermediate 2 min

A practical guide to Content-Security-Policy

CSP is the strongest defence against cross-site scripting. Learn what it controls, how to roll it out safely with report-only, and how to avoid unsafe-inline.

A Content-Security-Policy (CSP) tells the browser exactly which sources of script, style, images and other resources are allowed to load. If an attacker injects a <script> tag, a good CSP stops it running — which is why CSP is the single most effective mitigation for cross-site scripting (XSS).

The shape of a policy

A policy is a set of directives, each naming allowed sources. default-src is the fallback; more specific directives override it.

Content-Security-Policy: default-src 'self'; img-src 'self' data:; style-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'

Avoid 'unsafe-inline'

The moment you allow 'unsafe-inline' for scripts, CSP stops protecting you from injected scripts — the whole point. Instead, move inline scripts to files served from your own origin, or authorise the specific inline blocks you control with a hash or a per-request nonce.

script-src 'self' 'sha256-BASE64HASH='
# or
script-src 'self' 'nonce-RANDOMPERREQUEST'
When a hash or nonce is present, browsers ignore 'unsafe-inline' entirely — so you can't "add it just in case." That's by design.

Roll it out with report-only

Don't ship a strict policy blind. Deploy it in report-only mode first: the browser reports what would have been blocked without actually blocking anything, so you can find legitimate resources you forgot before enforcing.

Content-Security-Policy-Report-Only: default-src 'self'; report-uri /csp-report

Common pitfalls

  • Third-party widgets that inject inline script or load from many hosts — allowlist exactly what they need, nothing broader.
  • connect-src forgetting your analytics or API endpoints, silently breaking requests.
  • Edge providers injecting their own inline scripts that your hash doesn't cover — either disable that feature or account for it.
  • Using a nonce that isn't actually random per response — a fixed nonce is no better than unsafe-inline.

How to fix it

  1. Inventory what your pages load (script, style, images, fonts, connections, frames).
  2. Write a report-only policy and watch the reports for a few days.
  3. Tighten until there are no legitimate violations, then switch the header to enforcing.
  4. Re-scan and keep object-src 'none', base-uri 'self' and frame-ancestors locked down.

Glossary

Directive
One rule inside a CSP, e.g. script-src, naming the allowed sources for a resource type.
Nonce
A random token generated per response and placed on both the header and the trusted inline tag to authorise it.
XSS
Cross-site scripting: running attacker-controlled JavaScript in a victim's browser in the context of your site.
AstraScope checks for this automatically.
Scan your website