HackproofHacks
Web App Security 15 min read

HTTP Security Headers: The Complete Guide to Hardening Your Website

HTTP security headers are one of the cheapest, highest-impact defences you can add to a website. This guide explains each header that matters — CSP, HSTS, cookie flags, and more — what attack it stops, and the value to set.

Hassan Ansari

Hassan Ansari

A code card showing two hardened HTTP response headers: CSP and X-Content-Type-Options

HTTP security headers: the complete hardening guide

If you want the best security return for the least effort on a website, HTTP security headers are it. They’re configured once (at your web server, framework, or CDN), apply to every response automatically, and instruct the browser to enforce a set of protective behaviours that blunt entire classes of attack.

This guide walks through every header that matters in 2026: what it does, which attack it stops, and the value to set. You can check your own site against all of them for free with our HTTP Header Analyzer as you read.


What security headers are (and aren’t)

A security header is a response header that tells the browser to turn on a defensive behaviour: “only run scripts from my own origin,” “always use HTTPS,” “don’t let other sites frame me.” The browser enforces the instruction on the client side.

One thing to be clear about: headers are defence in depth, not a substitute for fixing vulnerabilities at the source. A Content-Security-Policy limits the damage of a cross-site scripting bug, but you should still eliminate the bug. Think of headers as the seatbelts and airbags of your site: essential, but not a reason to drive recklessly.

With that framing, here are the headers that earn their place.


Content-Security-Policy (CSP): the heavy hitter

CSP is the most powerful security header and also the hardest to get right. It tells the browser exactly which sources of content (scripts, styles, images, frames) are allowed to load and execute. MDN’s Content-Security-Policy reference documents every directive, and it is worth keeping open the first few times you write one. A strict CSP can neutralise cross-site scripting entirely: even if an attacker injects a <script>, the browser refuses to run it because it doesn’t come from an approved source.

A reasonable strict starting point:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'

The single most important rule: avoid 'unsafe-inline' in script-src. It’s the most common way sites accidentally throw away most of their CSP protection, because it re-permits exactly the inline scripts that XSS relies on. Modern strict CSPs use nonces or hashes to allow specific trusted inline scripts instead.

CSP takes tuning (you need to know every resource your site legitimately loads), which is why our analyzer includes a dedicated CSP linter to flag weak directives like unsafe-inline and overly broad sources.


Strict-Transport-Security (HSTS): enforce HTTPS

HSTS tells the browser to only ever connect to your site over HTTPS, for a set period, even if the user types http:// or follows an old insecure link. This closes the window for protocol-downgrade and man-in-the-middle attacks that depend on intercepting that first plaintext request.

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • max-age=31536000: remember the HTTPS-only rule for one year.
  • includeSubDomains: apply it to every subdomain too.
  • preload: allows inclusion in browsers’ built-in HSTS preload list, so the very first request is protected as well.

Only enable includeSubDomains and preload once you’re certain every subdomain supports HTTPS, since it’s a strong, sticky commitment. Pair HSTS with a valid, well-configured certificate. Check yours with the SSL/TLS Checker.


X-Content-Type-Options: stop MIME sniffing

X-Content-Type-Options: nosniff

Browsers sometimes try to guess (“sniff”) the type of a resource rather than trusting the declared Content-Type. That guessing can be abused to make the browser treat an uploaded file as executable script. nosniff disables the guessing and forces the browser to honour the declared type. It’s a one-line, no-downside header. Set it everywhere.


Clickjacking defence: frame-ancestors and X-Frame-Options

Clickjacking loads your site invisibly inside an attacker’s page and tricks users into clicking things they can’t see: approving a transaction, changing a setting. Two headers defend against it:

Content-Security-Policy: frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN

The modern control is CSP’s frame-ancestors directive, which precisely specifies which origins may frame your site. X-Frame-Options is the older, coarser header kept for compatibility with legacy browsers. Use frame-ancestors as the real control and keep X-Frame-Options alongside it.


Referrer-Policy: control what you leak

Referrer-Policy: strict-origin-when-cross-origin

When a user navigates from your site to another, the browser sends a Referer header telling the destination where they came from, which can leak sensitive path or query data in your URLs. strict-origin-when-cross-origin sends the full URL to same-origin destinations but only the bare origin to other sites, and nothing when downgrading from HTTPS to HTTP. A sensible privacy-preserving default.


Permissions-Policy: disable features you don’t use

Permissions-Policy: camera=(), microphone=(), geolocation=()

Permissions-Policy (formerly Feature-Policy) lets you switch off powerful browser features your site doesn’t need: camera, microphone, geolocation, and more. Disabling unused features shrinks the attack surface: if your site never uses the camera, denying it means an injected script can’t try to either.


Not headers in the strict sense, but set via the Set-Cookie header, and critical enough that no hardening guide is complete without them:

Set-Cookie: session=...; HttpOnly; Secure; SameSite=Lax
  • HttpOnly: JavaScript cannot read the cookie, so a successful XSS payload can’t simply steal the session token via document.cookie.
  • Secure: the cookie is only ever sent over HTTPS, never in plaintext.
  • SameSite=Lax (or Strict): the cookie isn’t sent on cross-site requests, which mitigates cross-site request forgery (CSRF).

Together these three flags dramatically harden session cookies against the most common session-theft techniques. Our analyzer includes a cookie audit that checks each of these on every cookie your site sets.


Headers you should not rely on

Security advice ages, and some once-recommended headers are now obsolete:

  • X-XSS-Protection controlled a legacy browser XSS filter that modern browsers have removed and that could itself introduce issues. Set it to 0 or omit it, and rely on CSP instead. If a scanner still demands it, the scanner is outdated.
  • Public-Key-Pins (HPKP) is deprecated and dangerous: a misconfiguration could lock users out of your site. Don’t use it.

Knowing what not to set is as valuable as knowing what to set.


A practical rollout plan

Adding headers carelessly can break a site: a too-strict CSP can block your own scripts. Roll them out deliberately:

  1. Start with the safe, no-downside headers: X-Content-Type-Options: nosniff, Referrer-Policy, X-Frame-Options/frame-ancestors, and the cookie flags.
  2. Add HSTS once you’ve confirmed HTTPS works everywhere, starting with a shorter max-age before committing to a year and preload.
  3. Tackle CSP last and carefully. Build it up from default-src 'self', add the specific sources your site genuinely needs, test thoroughly, and use report-only mode first to catch what it would break before you enforce it.
  4. Scan, fix, re-scan. Run your site through the HTTP Header Analyzer, work down the prioritised list of gaps with its platform-specific fix snippets, then re-scan to confirm.

Key takeaways

  • Security headers are cheap, high-impact hardening: configured once, enforced by the browser on every response.
  • CSP is the most powerful (avoid unsafe-inline), HSTS enforces HTTPS, and the cookie flags protect sessions.
  • Simple wins like nosniff, frame-ancestors, Referrer-Policy, and Permissions-Policy add up fast.
  • Some old headers (X-XSS-Protection, HPKP) should no longer be used.
  • Roll out carefully, especially CSP, and verify with a scanner.

Headers won’t fix a broken application on their own, but they turn many would-be catastrophes into non-events. For the effort involved, nothing else on your security checklist pays off as reliably.

For a second opinion on your configuration, securityheaders.com grades any public site in seconds, Mozilla’s SSL Configuration Generator produces a matching TLS setup for your web server, and Qualys SSL Labs audits the certificate chain and cipher suites behind it. The underlying HTTP semantics are specified in RFC 9110.

Check your site now with the free HTTP Header Analyzer, learn how CSP stops attacks in the XSS guide, and see the bigger picture in the OWASP Top 10 breakdown.

#security headers #CSP #HSTS #web security #hardening #cookies
Free newsletter

Liked this? I write one like it every week.

One practical security lesson in your inbox each week, explained the same simple way. Join 10,000+ readers. Unsubscribe anytime.

From the article

Need a security assessment?

HackproofHacks provides web application and API penetration testing — using the same techniques covered in this article, with your explicit authorisation.

Book a free scoping call

More on Web App Security.

All articles →
FAQ

Questions about this topic.

What are HTTP security headers?

HTTP security headers are special response headers a web server sends alongside a page that instruct the browser to enable protective behaviours. They're a set of directives — like 'only load scripts from my own domain' or 'always use HTTPS for this site' — that the browser enforces on the client side. Because they're configured once at the server or CDN level and apply to every response, they're among the cheapest and highest-impact hardening steps available, reducing the impact of attacks like cross-site scripting, clickjacking, and protocol downgrade.

What is the most important security header?

Content-Security-Policy (CSP) is generally the most powerful, because a well-configured CSP can neutralise cross-site scripting — one of the most common serious web vulnerabilities — by refusing to execute untrusted or inline scripts. It's also the hardest to configure correctly, since it requires knowing exactly which resources your site legitimately loads. After CSP, HTTP Strict-Transport-Security (HSTS) is a close second in importance because it forces browsers to always use HTTPS, and the cookie security flags matter enormously for protecting sessions.

What does HSTS (Strict-Transport-Security) do?

HSTS tells the browser to only ever connect to the site over HTTPS, for a specified duration, even if a user types http:// or clicks an old http link. This prevents protocol-downgrade and man-in-the-middle attacks that rely on intercepting an initial insecure request. Once a browser has seen the HSTS header, it automatically upgrades all future requests to that domain to HTTPS before sending anything, closing the small but real window where an attacker could hijack a plaintext connection.

Is X-XSS-Protection still recommended?

No. The X-XSS-Protection header controlled a legacy browser feature that has been removed from modern browsers, and it could even introduce vulnerabilities in some configurations. The current best practice is to set it to '0' to disable the old filter, or omit it, and rely on a strong Content-Security-Policy for XSS defence instead. If a scanner still flags its absence, that scanner is out of date — CSP is the modern replacement.

What's the difference between X-Frame-Options and CSP frame-ancestors?

Both defend against clickjacking — an attack where your site is loaded invisibly inside an attacker's page to trick users into clicking things. X-Frame-Options is the older header and offers coarse control (deny all framing, or allow only same-origin). The CSP frame-ancestors directive is the modern, more flexible replacement that lets you specify exactly which origins may frame your site and supports multiple allowed origins. Best practice is to use frame-ancestors in your CSP, and you can keep X-Frame-Options for older browser compatibility.

How do I check my website's security headers?

You can inspect them directly in your browser's developer tools under the network tab, but a dedicated analyzer is faster and explains what each header means and what's missing. Our free HTTP Header Analyzer scans any URL, grades its security-header posture, lints your Content-Security-Policy for weaknesses, audits cookie flags, and gives platform-specific fix snippets — so you get a prioritised checklist rather than a raw dump. Run your site through it, fix the gaps, and re-scan to confirm.