Security Headers Explained: The Complete 2026 Guide
Security headers are the cheapest security upgrade you can make. They cost nothing to implement, take minutes to add, and block entire categories of attacks — yet over 30% of the top 10,000 websites still ship with missing or misconfigured headers.
This guide covers every HTTP security header that matters in 2026, what each one does, the exact values to set, and how to audit your site without installing anything.
#Why security headers matter
When a browser loads your site, it has no built-in knowledge about what your content should look like or how it should behave. Security headers are instructions from your server that tell the browser what to allow and what to block.
Without them, an attacker can:
- Inject scripts into your pages (XSS)
- Embed your site in a frame to steal user input (clickjacking)
- Intercept HTTP traffic before it reaches HTTPS (MITM)
- MIME-sniff responses into executable content (MIME confusion)
Each header closes one or more of these doors.
#The essential five
#1. Content-Security-Policy (CSP)
CSP is the single most powerful security header. It tells the browser exactly which sources are allowed to load scripts, styles, images, fonts, and other resources.
Recommended starting policy:
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.your-site.com; frame-ancestors 'self'; object-src 'none'; base-uri 'self'; form-action 'self'
Key directives:
script-src— controls where JavaScript can load from.'unsafe-inline'is required for frameworks like Next.js that inline hydration scripts. Move to nonces when possible.frame-ancestors— replacesX-Frame-Optionswith finer control over who can embed your page.object-src 'none'— blocks Flash and Java plugins entirely (should always be'none'in 2026).base-uri 'self'— prevents attackers from injecting a<base>tag to hijack relative URLs.
Common mistake: deploying a strict CSP without report-only mode first. Use Content-Security-Policy-Report-Only for 1-2 weeks, collect violations via a /csp-report endpoint, then tighten.
Learn more: MDN Content-Security-Policy reference, Google CSP Evaluator
#2. Strict-Transport-Security (HSTS)
HSTS forces browsers to only connect over HTTPS for a specified duration, preventing SSL stripping attacks.
Recommended value:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
max-age=63072000— 2 years. This is the minimum for HSTS preload list submission.includeSubDomains— applies to all subdomains. Only use if every subdomain supports HTTPS.preload— allows inclusion in browser preload lists (ships HTTPS-only by default).
Common mistake: setting HSTS before your entire domain supports HTTPS. If any subdomain serves HTTP, includeSubDomains will break it permanently for returning visitors.
Learn more: MDN Strict-Transport-Security, OWASP HSTS cheat sheet
#3. X-Content-Type-Options
X-Content-Type-Options: nosniff
This is the simplest and safest header. It prevents browsers from MIME-sniffing a response into a different content type than what the server declared. Without it, a file served as text/plain could be executed as JavaScript.
No configuration needed. Always set it. There is no reason not to.
Learn more: MDN X-Content-Type-Options
#4. X-Frame-Options
X-Frame-Options: DENY
Prevents your page from being embedded in an <iframe>, <frame>, or <object> on another site. This blocks clickjacking attacks where an attacker overlays your login form with a transparent iframe.
DENY— no framing at all (most restrictive, preferred)SAMEORIGIN— allow framing by pages on the same domain (needed if you frame your own content)
Note: frame-ancestors in CSP supersedes this header. If you set both, CSP wins in modern browsers. Set DENY as a fallback for older browsers.
Learn more: MDN X-Frame-Options
#5. Referrer-Policy
Referrer-Policy: strict-origin-when-cross-origin
Controls how much URL information the browser sends in the Referer header when navigating to other pages. This prevents leaking sensitive URLs (tokens, internal paths) to third-party sites.
Best values:
strict-origin-when-cross-origin— full URL for same-origin, origin-only for cross-origin, nothing for downgrade (HTTP→HTTPS). Best balance of security and functionality.no-referrer— never send the referer. Most private but breaks analytics.same-origin— only send for same-origin navigations.
Learn more: MDN Referrer-Policy
#The recommended supporting headers
#Permissions-Policy
Controls access to browser features like camera, microphone, geolocation, and payment API.
Permissions-Policy: camera=(), microphone=(), geolocation=(), payment=(), usb=(), browsing-topics=()
Empty parens () means deny to all origins (including your own). If you need a feature, use self for same-origin only.
Learn more: MDN Permissions-Policy
#Cross-Origin-Opener-Policy (COOP)
Cross-Origin-Opener-Policy: same-origin
Isolates your browsing context. Prevents cross-origin attackers from accessing your window.opener reference, which could be used to redirect your page.
Learn more: MDN COOP
#Cross-Origin-Resource-Policy (CORP)
Cross-Origin-Resource-Policy: same-origin
Prevents your resources (images, scripts, CSS) from being loaded by other origins. Blocks Spectre-style side-channel attacks that abuse cross-origin resource loading.
Learn more: MDN CORP
#Quick audit with curl
You can check any site's headers from your terminal:
curl -I https://example.com 2>/dev/null | grep -iE '(content-security-policy|strict-transport|x-content-type|x-frame-options|referrer-policy|permissions-policy)'
Or paste the URL into Vergate's free scanner to get a scored report with specific fix suggestions for every missing header.
#Common mistakes
| Mistake | Why it's bad |
|---|---|
X-Frame-Options: ALLOWALL | Equivalent to no protection — any site can frame you |
CSP with unsafe-eval | Allows eval() — defeats the purpose of CSP for XSS prevention |
HSTS with short max-age | Under 1 hour means browsers forget quickly, leaving gaps |
Missing object-src 'none' | Leaves Flash/plugin injection open even with a good CSP |
| Setting headers on HTTP only | Browsers ignore security headers on non-HTTPS connections |
#How Vergate checks security headers
Vergate's passive scanner checks all 8 headers discussed in this post during every scan. Missing headers are flagged by severity (Critical for CSP and HSTS, Medium for X-Frame-Options, Low for the rest), and each finding comes with a copy-paste remediation snippet.
Run a free scan at vergate.dev/free-scan to see your current header posture — no signup required.
#Further reading
- OWASP Secure Headers Project — comprehensive reference for every HTTP header
- MDN HTTP Security Headers — browser documentation for each header
- Google Web Fundamentals: Security — practical implementation guides
- Mozilla Observatory — free header grading tool
Frequently asked questions
What are the most important HTTP security headers?
Content-Security-Policy (CSP), Strict-Transport-Security (HSTS), X-Content-Type-Options, X-Frame-Options, and Referrer-Policy are the five headers every site should implement. CSP prevents XSS, HSTS enforces HTTPS, and the others block clickjacking, MIME sniffing, and data leakage.
How do I check my website's security headers?
Use a security scanner like Vergate, or check manually with curl -I https://your-site.com. Tools like [Mozilla Observatory](https://observatory.mozilla.org/) and [SecurityHeaders.com](https://securityheaders.com/) also grade your header configuration.
Can security headers break my website?
Yes, if misconfigured. A strict CSP can block legitimate scripts, and a wrong X-Frame-Options can break embedded content. Always test with report-only mode first — CSP supports Content-Security-Policy-Report-Only to preview violations without blocking.
Do security headers protect against all attacks?
No. Security headers are one layer of defense-in-depth. They mitigate specific attack classes (XSS, clickjacking, MITM) but don't replace secure coding practices, input validation, or server-side protections.