Learn

Content Security Policy (CSP) monitoring guide

A good CSP turns most XSS bugs into harmless 404s in the console. Here is how to write one that holds up, without breaking your own scripts.

What it is

Content-Security-Policy (CSP) is a response header that restricts where scripts, styles, images, and other resources can load from. It reduces the impact of XSS and data injection by blocking unauthorized sources.

Why it matters

Without CSP, a single XSS can load and run any script. CSP limits the damage. A well-configured CSP is a strong defense-in-depth measure. Monitoring catches missing or weak policies.

How Barrion checks it

Barrion inspects the Content-Security-Policy (and Report-Only) header. We check for presence, key directives (default-src, script-src, frame-ancestors), and dangerous values like 'unsafe-inline' or 'unsafe-eval' where they increase risk. Passive header check only.

Configuration examples

Nginx: strict baseline CSP
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; object-src 'none'; frame-ancestors 'none'; base-uri 'self'" always;

Verify it

curl -sI https://example.com | grep -i content-security-policy
Run this check →Fix guide

References

Related

FAQ

Common questions.

Why is 'unsafe-inline' such a problem?
It tells the browser to execute any inline script or style, which is exactly the surface an XSS payload uses. A policy with script-src 'unsafe-inline' provides almost no protection against injected scripts and is treated as missing by most CSP scanners.
How do I migrate from a permissive CSP without breaking the app?
Deploy your target policy in Content-Security-Policy-Report-Only first and collect violations via report-to or report-uri for a week or two. Fix the legitimate ones (move inline handlers to event listeners, add nonces, allow-list third parties), then promote the same policy to enforcing mode.
Do I need nonces or hashes?
If you have any inline scripts you cannot remove, yes. Nonces are easier when the HTML is rendered per-request (generate a fresh random value, attach it to the script tag and to script-src), while hashes work for static markup because they pin a specific script body. Strict-dynamic plus a nonce is the modern recommendation.
Should script-src cover everything, or do I need object-src and base-uri too?
Cover all three. object-src 'none' kills Flash and legacy plugin vectors, base-uri 'self' stops an XSS from rewriting relative URLs by injecting a <base> tag, and frame-ancestors replaces X-Frame-Options. Strict CSP guides treat these as required directives rather than optional extras.