Headers
Content Security Policy: the header that stops most XSS attacks dead.
Published 2026-05-12 · Last updated 2026-05-12 · Vantyris editorial
Content Security Policy (CSP) is a header that tells the browser which sources your page may load scripts from, and the same for styles, fonts and images. Without it, a script injected through a compromised plugin or a clever XSS bug can run and send your visitors' data wherever the attacker likes. With it, the browser refuses to run anything from a source you haven't explicitly allowed. CSP is the single header that prevents the most common class of website attacks.
What this means for your business
- Most small business sites have no CSP at all. The browser loads and runs anything the page references, including malicious scripts injected through a vulnerable form, a compromised CMS plugin, or a third-party widget that got hacked.
- A useful CSP doesn't have to be complicated. Even a basic policy that allows scripts only from your own domain stops the vast majority of XSS attacks.
- CSP is tricky to add to an existing site because the policy has to allow everything your site already uses. Start in
report-onlymode and browser DevTools shows you what would be blocked, so you can fix the policy before enforcing it.
How to fix
Start with Content-Security-Policy-Report-Only (observe mode) and watch the browser report violations for a week. Fix the policy until the reports are clean, then switch to the enforcing Content-Security-Policy header.
- Audit what your site already loads. Open your site with Chrome DevTools on the Network tab. Write down every outside domain the page loads anything from (scripts, styles, fonts, images, frames). The common ones are Google Fonts, Stripe, your CDN, analytics tools and embedded YouTube.
- Draft a basic policy. A reasonable starting point:
default-src 'self'; script-src 'self' https://js.stripe.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' https://fonts.gstatic.com; frame-ancestors 'none'; form-action 'self'. Adjust the third-party domains to match your stack. - Deploy in report-only mode first. Send the header as
Content-Security-Policy-Report-Only(note the suffix). The browser logs violations to the console but doesn't block anything. Use your site normally for a week and watch the console forRefused to loadmessages. Each one names a domain your policy missed. - Tighten the policy until clean. Add the missing domains to the relevant directive. Better still, refactor the site to use fewer external services. Every
https://allowance in your CSP is a tradeoff. - Switch to enforcing mode. Rename the header from
Content-Security-Policy-Report-OnlytoContent-Security-Policy. Now the browser enforces it.
Owner: Your developer or web host. · Time: 1-2 hours of audit + 1 week of observe-mode + 30 minutes to flip on.
Common gotchas
'unsafe-inline'onscript-srcdefeats most of CSP's value. Avoid it. If you need inline scripts (legacy CMS templates), use a nonce instead.'unsafe-eval'is needed by some older JS frameworks (Vue's runtime compiler, certain dev modes). Avoid it in production.- If your site embeds anything via
<iframe>(YouTube, Stripe checkout, Calendly), those embeds needframe-srcallowances. - Don't deploy a strict CSP without observe-mode first. You will break something you didn't know was there.
How to verify the fix
Run a Vantyris scan. It checks that a CSP is present and flags the common weaknesses ('unsafe-inline', 'unsafe-eval', a missing default-src). For a detailed CSP grade, run your site through observatory.mozilla.org.
Cyber Essentials alignment
This finding informs the following Cyber Essentials control areas (the UK government's baseline scheme, a sound checklist in any country):
- A2. Secure configuration: devices and services hardened against the weaknesses they ship with by default.
Vantyris is not a CE certifying body. The mapping above is informational.
Common follow-up questions
Do I need CSP if I have HTTPS?
Yes. HTTPS encrypts the connection. CSP controls what code runs on the page. Different protections, different threats.
Will CSP break my analytics?
Only if your analytics runs on a domain you didn't allow. Add the analytics domain to script-src and connect-src and it works fine.
What's the difference between CSP and Permissions-Policy?
CSP controls what code runs. Permissions-Policy controls which browser features the page can use (camera, microphone, geolocation, etc.). Different headers that complement each other.
References
Related explainers
- HSTS: the security header that locks HTTPS on for good.
- X-Frame-Options and frame-ancestors: the anti-clickjacking header.
Want Vantyris to check your domain for this and 196 other problems?
The teaser scan is free and needs no card. A verified scan starts at $10€10£10A$15¥1,500AED 40 and comes with the workspace: finding workflow, score trend, three PDF layouts, share links and monitoring.
Written by Vantyris