TL;DR
Security headers are the cheapest hardening on the web, a handful of HTTP response lines that defend against XSS, clickjacking, protocol downgrade, and MIME confusion, and most sites still ship without them. Per the 2025 Web Almanac, HSTS reaches only about 36% of mobile pages, with just ~22% using the preload directive, and strong Content-Security-Policy adoption is far lower. That gap is the first thing a security questionnaire, a penetration tester, and an attacker all check, which is why a missing CSP or HSTS header is a documented reason enterprise deals stall in security review. The fix takes an afternoon and zero new infrastructure: you are adding text to responses you already send.
The free defense almost nobody fully deploys
Most web security work is hard: input validation, auth flows, dependency hygiene, threat modeling. Security headers are the exception. They are a small set of HTTP response headers that instruct the browser to enforce protections on your behalf, and the browser already supports all of them. There is no library to install, no architecture to change, no performance cost worth mentioning. You add lines to the responses your server is already sending. The return on effort is among the highest in all of application security.
And yet adoption is strikingly thin. Per the HTTP Archive Web Almanac 2025 security chapter, HSTS, the header that forces HTTPS, reaches only about 36% of mobile pages, and even among sites that deploy it, only ~22% use the preload directive that protects the very first visit. Content-Security-Policy, the single most effective defense against cross-site scripting, lags further still, with strict nonce-based policies remaining rare even where CSP exists at all. The free defense is sitting unused on the majority of the web, not because it is hard, but because nobody owns it.
The headers that earn their keep
Not all headers are equal. A handful do the heavy lifting, and these are the ones a scan will flag and an auditor will expect.
Content-Security-Policy (CSP), the XSS firewall
CSP tells the browser which sources of scripts, styles, and other resources are allowed to load and execute. A strong CSP turns a cross-site scripting vulnerability from "attacker runs arbitrary JavaScript" into "browser refuses to run the injected script." It is the most powerful header and the hardest to deploy correctly, because a too-loose policy (unsafe-inline, wildcards) provides little protection while a too-strict one breaks the site. The modern best practice, per the OWASP Secure Headers Project, is a nonce-based strict-dynamic policy that trusts scripts by a per-request nonce rather than by host allowlists.
HSTS, no more downgrade attacks
HTTP Strict Transport Security tells the browser to only ever connect over HTTPS for your domain, eliminating the window where a man-in-the-middle can intercept an initial HTTP request and downgrade the connection. With includeSubDomains and preload, the protection extends to subdomains and even the first-ever visit, before the browser has ever seen your site. Without preload, the very first request to your domain can still be intercepted; with it, the browser refuses HTTP from the start.
X-Frame-Options / frame-ancestors, anti-clickjacking
These prevent your site from being embedded in an attacker's iframe, which defeats clickjacking attacks that overlay your real page with invisible elements to trick users into clicking things they did not intend, approving a transfer, changing a setting, granting a permission. The modern form is the CSP frame-ancestors directive; X-Frame-Options remains for older browsers.
X-Content-Type-Options, stop MIME sniffing
A single header value, nosniff, stops the browser from second-guessing your declared content types, which closes a class of attacks where a file uploaded as an image is interpreted and executed as a script.
Referrer-Policy and Permissions-Policy
Referrer-Policy controls how much URL information leaks to other sites in the Referer header, preventing sensitive paths and query parameters from leaking to third parties. Permissions-Policy lets you disable powerful browser features (camera, microphone, geolocation) you do not use, shrinking your attack surface and limiting what a compromised script could request.
A real, deployable configuration
Here is a starting configuration that covers the high-value headers. The CSP is the part that needs tuning to your actual asset origins, start in report-only mode, watch the violations, then enforce.
# nginx, high-value security headers
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# CSP, nonce-based, strict-dynamic (the strong form).
# Generate a fresh nonce per response and add it to your <script> tags.
add_header Content-Security-Policy
"default-src 'self';
script-src 'nonce-$request_id' 'strict-dynamic' https:;
object-src 'none';
base-uri 'none';
frame-ancestors 'none';
upgrade-insecure-requests" always;
The frame-ancestors 'none' directive replaces a separate X-Frame-Options: DENY for modern browsers, base-uri 'none' blocks a class of injection that rewrites the document base URL, and upgrade-insecure-requests automatically rewrites any stray http:// subresource to https://, which doubles as a mixed-content fix. The always flag matters in nginx, without it, headers are dropped on error responses, leaving your 404 and 500 pages unprotected.
Content-Security-Policy-Report-Only mode first. It sends violation reports without blocking anything, so you can discover every inline script and third-party origin your site actually uses before you enforce, turning the scary "CSP will break my site" risk into a measured rollout. Watch the reports for a week, fix or allowlist what is legitimate, then flip to enforcing.
The trap: a header that exists but does nothing
A subtle failure mode is worse than a missing header: a header that is present but misconfigured, giving you a false sense of security and a passing checkbox while providing no real protection. The classic example is a CSP full of unsafe-inline and wildcard sources, it technically exists, a naive checklist marks it green, but it blocks essentially nothing because it permits exactly the inline injection it is supposed to stop. Per the 2025 analysis of HTTP security headers that matter, the gap between "has a CSP" and "has an effective CSP" is enormous, and only the latter actually stops XSS.
The same trap applies elsewhere. An HSTS header with a 60-second max-age offers almost no protection. An X-Frame-Options set to ALLOW-FROM (deprecated and widely ignored) is no protection at all. A Referrer-Policy of unsafe-url actively leaks more than the default. This is why a real scan grades the content of headers, not just their presence, a check that confirms a header exists but ignores whether its value is meaningful is reporting compliance you do not have, which is arguably worse than knowing you have none.
Headers as a sales blocker, not just a security one
For B2B and enterprise teams there is a direct revenue angle. Vendor security reviews, SOC 2 audits, and enterprise procurement questionnaires routinely include questions about transport security and browser hardening, and an automated external scan is often the first step a prospect's security team runs against you, before they even take a call. A clean header profile sails through; a missing HSTS or absent CSP becomes a finding that delays the deal while you remediate and re-attest, sometimes pushing a close into the next quarter.
Per the securityheaders.com analysis tool, which grades any domain's header profile in seconds and assigns a letter grade, this is exactly the kind of check buyers run before they trust you with their data. A poor grade is a poor first impression at the worst possible moment, when someone is actively evaluating whether your company is safe to integrate with. The headers are free to deploy and expensive to be caught without.
Verify and keep it verified
Headers regress like anything else: a new CDN strips them, a framework upgrade changes defaults, a developer removes one to debug and forgets to restore it, or a new route serves responses through a path that bypasses the header middleware. Assert your header profile in CI so a deploy that drops or weakens a security header fails the build, and scan production on a schedule because edge and CDN config can change outside your deploy pipeline entirely.
# CI gate: assert the high-value headers are present and strong
const res = await fetch(url, {method: 'HEAD'});
const h = res.headers;
const hsts = h.get('strict-transport-security') || '';
const csp = h.get('content-security-policy') || '';
const checks = [
[/max-age=\d{5, }/.test(hsts) && !/max-age=0\b/.test(hsts), 'HSTS (long max-age)'],
[csp && !/unsafe-inline/.test(csp), 'strong CSP (no unsafe-inline)'],
[h.get('x-content-type-options') === 'nosniff', 'nosniff'],
[/frame-ancestors|deny|sameorigin/i.test(csp + (h.get('x-frame-options')||'')),
'anti-clickjacking'],
];
const failed = checks.filter(([ok]) => !ok).map(([, name]) => name);
if (failed.length) { console.error('Missing/weak:', failed.join(', ')); process.exit(1); }
The bottom line
Security headers are free, fast, and effective, and most sites still leave them on the table, HSTS on barely a third of pages, strong CSP rarer still. Each missing header is an open door that XSS, clickjacking, downgrade, and MIME-confusion attacks walk through, and each one is also the first finding a security questionnaire or penetration test surfaces, which is how an absent CSP turns into a stalled enterprise deal. Deploy the high-value set, CSP (nonce-based, report-only first), HSTS with preload, frame-ancestors, nosniff, verify that they are not just present but strong, and gate them in CI plus scan production on a schedule. A scan that grades the content of your headers, not just their existence, closes the gap in an afternoon and keeps it closed.
Find the Gaps Before They Cost You
Scan audits your site for the accessibility, performance, AEO, and security gaps that quietly drain revenue and invite lawsuits, in one pass.
Try Scan Free →