HTTP security headers: the minimum worth setting today
CSP, HSTS, X-Content-Type-Options and the rest: what actually protects you, what is obsolete, and in which order to roll them out without an outage.
Security · Published: 10 June 2026 · 3 min read · Марк Лебедев
Security headers are one of the rare cases where a few lines of configuration close whole classes of attack. And one of the rare cases where a careless rollout breaks the site in seconds. So the order matters as much as the content.
Start with the safe ones
These three can be enabled with almost no risk:
X-Content-Type-Options: nosniff — stops the browser guessing content types. It closes the scenario where a user-uploaded "text" file is executed as a script.
Referrer-Policy: strict-origin-when-cross-origin — stops leaking the full page path into somebody else's analytics. It is the browser default today, but stating it explicitly is more reliable.
Strict-Transport-Security: max-age=31536000; includeSubDomains — HSTS forces HTTPS. Careful: enable it only once the whole site and every subdomain already run on HTTPS. There is no fast rollback — browsers remember the header for the entire max-age. Start at max-age=300, confirm nothing broke, then raise it.
CSP — the most useful and the most dangerous
Content-Security-Policy declares where scripts, styles and images may be loaded from. It blocks most XSS, and it takes the site down if the policy was written on a hunch.
The right path has three steps:
- Turn on observation mode:
Content-Security-Policy-Report-Onlywith a reporting endpoint. Nothing is blocked, but you see what would be. - Collect reports for a couple of weeks and add everything legitimate to the policy — widgets, fonts, analytics.
- Switch to the enforcing header.
A minimal sensible policy for a site without inline scripts:
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; img-src 'self' data:; frame-ancestors 'none'; base-uri 'self'
The frame-ancestors 'none' directive supersedes the obsolete X-Frame-Options and closes clickjacking.
What is no longer needed
X-XSS-Protection is obsolete: modern browsers ignore it, and in older ones it was itself a vulnerability. Feature-Policy has been renamed Permissions-Policy.
How to verify
Headers are set at several layers — CDN, reverse proxy, application — and are easily lost or duplicated when infrastructure changes. Check the actual response, not the configuration, across several URL types: the homepage, a route from the SPA router, a static file, an API endpoint. The differences between them are the most common audit finding.
And watch for regressions: a header accidentally dropped during a move to a new CDN gives no signal until it is too late.
Read next
Check how much of this is on your own site
A free scan surfaces broken links, JS errors and performance problems in about a minute.