Security headers are HTTP response headers that tell browsers how to behave when handling your site's content. They're one of the highest-leverage, lowest-cost security improvements a website can make — and most sites still have them wrong or missing.
Why security headers matter
Browsers trust websites by default. Without explicit instructions, a browser will:
- Execute any JavaScript included in page HTML (XSS vector)
- Load your site inside an iframe on any other domain (clickjacking vector)
- Guess content types for ambiguous files (MIME confusion vector)
- Allow your site to be accessed over HTTP even when HTTPS is available
- Send your full URL as a referrer header to third-party resources
Security headers close these default behaviours one by one.
Content-Security-Policy (CSP)
The most powerful and most complex security header. CSP tells the browser exactly which sources of content (scripts, styles, images, fonts, iframes) are allowed to load on your page.
What it prevents: Cross-site scripting (XSS) attacks that inject malicious scripts into your pages; data exfiltration via injected requests to attacker-controlled servers.
Basic example:
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-{random}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none'
Practical guidance: Start with CSP in report-only mode (`Content-Security-Policy-Report-Only`) to see what would be blocked without breaking anything. Then tighten the policy based on the report. Never ship a CSP with `default-src *` — this defeats the purpose.
Strict-Transport-Security (HSTS)
What it does: Tells the browser to only ever connect to your site over HTTPS — never HTTP — for the duration specified.
What it prevents: SSL stripping attacks where an attacker intercepts your HTTP→HTTPS redirect and downgrades the connection.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
Caution: Once set with a long `max-age`, removing HTTPS from your site will break it for returning visitors for the duration of the max-age. Set `preload` only after you're confident your site will remain HTTPS permanently.
X-Frame-Options
What it does: Controls whether your site can be embedded in an iframe on another domain.
What it prevents: Clickjacking — an attack where your site is loaded in a transparent iframe and the user is tricked into clicking on UI elements they can't see.
X-Frame-Options: DENY
Note: CSP's `frame-ancestors` directive supersedes X-Frame-Options in modern browsers. Set both for legacy browser compatibility.
X-Content-Type-Options
What it does: Prevents the browser from MIME-sniffing a response away from the declared content type.
What it prevents: MIME confusion attacks where an attacker uploads a file that's treated as a different, more dangerous type.
X-Content-Type-Options: nosniff
This is a one-liner with no downside. Set it everywhere.
Referrer-Policy
What it does: Controls how much URL information is included in the `Referer` header sent to third parties when users click links on your site.
What it prevents: Leaking sensitive URL parameters (session tokens, user IDs, search queries) to third-party analytics, CDN, or advertising partners.
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy
What it does: Restricts which browser features (camera, microphone, geolocation, payment) your site and its embedded iframes can use.
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=()
How to check your current header score
Use our Website Security Checker to see which headers your site sets and which are missing. For Apache deployments, headers are set in `.htaccess`. For nginx, in the server block. For Cloudflare, in Transform Rules or Workers. Check our full guide at Cybersecurity Checklist for Small Business for the broader security picture.