security
How to fix: Content-Security-Policy present
OWASP A05
NIS2 Art. 21(2)(a)
Why this matters
Content-Security-Policy is the strongest defence-in-depth control against cross-site scripting. It limits which sources can load scripts, styles, and other resources — so even if an attacker injects HTML, the browser refuses to execute it.
Background
A Content-Security-Policy header instructs the browser which origins are allowed to load scripts, styles, images, frames and other resources on your page. Done well, it neutralises the impact of a successful XSS or supply-chain compromise — the attacker's injected script simply doesn't execute because its source isn't on the allowlist. The catch: a CSP that uses 'unsafe-inline' or wildcard sources offers false comfort with little real protection.
References
OWASP A05 (Security Misconfiguration) · CSP Level 3 (W3C) · MDN: Content-Security-Policy
How to fix
Code snippet for each stack we cover. Pick the one matching your server / framework.
nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{nonce}'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests" always;
apache
Header always set Content-Security-Policy "default-src 'self'; script-src 'self' 'nonce-{nonce}'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'; form-action 'self'; upgrade-insecure-requests"
cloudflare
Transform Rules → Modify Response Header → set Content-Security-Policy with the same value as above. Test in Report-Only mode first.
wordpress
Install the WP Headers Security Advanced plugin OR add to functions.php: add_action('send_headers', function () { header("Content-Security-Policy: default-src 'self'; ..."); });
flask
@app.after_request
def _csp(resp):
resp.headers['Content-Security-Policy'] = "default-src 'self'; ..."
return resp
express
app.use(helmet.contentSecurityPolicy({ directives: { defaultSrc: ["'self'"], scriptSrc: ["'self'", (req,res) => `'nonce-${res.locals.cspNonce}'`], objectSrc: ["'none'"] } }))
rails
# config/initializers/content_security_policy.rb Rails.application.config.content_security_policy do |p| p.default_src :self p.script_src :self p.object_src :none end
Verify it's working
curl -sI https://your-site/ | grep -i 'content-security-policy:'
Want to know if your site has this issue?
Run a free 53-check audit — security, GDPR, NIS2, and technical SEO.
Audit my site →