Add or fix a Content-Security-Policy header
Your site has no CSP header or a weak one. Here is a starter policy that blocks 90% of XSS without breaking your site.
What is happening
A Content-Security-Policy (CSP) header tells the browser which sources are allowed to load scripts, styles, images, and other content. Without it, any XSS bug becomes a full site takeover.
Starter policy (report-only first)
Add this header in report-only mode for a week so you can find violations without breaking anything:
Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; connect-src 'self' https:; frame-ancestors 'none'; report-uri /csp-reportAfter a week of zero violations on real traffic, switch Content-Security-Policy-Report-Only → Content-Security-Policy to enforce.
Strict policy (after audit)
Once you have removed inline scripts and styles:
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'nonce-{random}'; img-src 'self' data: https:; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'Generate a fresh nonce per request on the server and pass it into every <script nonce="..."> tag.
Where to set the header
add_header Content-Security-Policy "..." always; in the server block.Header set Content-Security-Policy "..." in .htaccess._headers file or edge middleware.helmet package or a middleware that sets the header.Common gotchas
script-src.frame-ancestors 'self' https://partner.com.What this doesn't do
CSP does not protect against CSRF, click-jacking outside of frame-ancestors, or backend SSRF. Add SameSite cookies, CSRF tokens, and request validation separately.