HSTS Explained — Stop SSL Stripping with Strict-Transport-Security
You redirect HTTP to HTTPS, so you're safe — right? Not quite. The very first request a browser makes is often plain HTTP, and that single unencrypted hop is enough for an attacker on the same network to perform SSL stripping: silently keeping the victim on HTTP while talking HTTPS to your server. HTTP Strict Transport Security (HSTS) closes that window.
What HSTS does
When a browser sees an HSTS header over HTTPS, it remembers — for the duration you specify — that this domain must only be reached over HTTPS. After that, the browser upgrades every request to HTTPS before it leaves the device, so there's no HTTP hop left to intercept.
The header
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Three parts:
max-age— how long (in seconds) the browser enforces HTTPS.63072000is two years, the recommended value. Anything under six months is considered weak.includeSubDomains— applies the rule to every subdomain. Make sure all of them serve HTTPS first, or you'll lock yourself out of HTTP-only subdomains.preload— opts you into the browser preload list (see below).
Roll it out carefully
HSTS is sticky by design — that's the point — but it also means a mistake is sticky. Deploy in stages:
- Confirm your whole site and all subdomains work over HTTPS.
- Start with a short
max-age, e.g.300(5 minutes), and verify nothing breaks. - Raise it to a day, then a week, then the full two years.
- Only add
includeSubDomainsonce every subdomain is HTTPS-ready.
The preload list
preload lets you submit your domain to a list baked directly into browsers, so HTTPS is enforced even on a user's very first visit. Submit at hstspreload.org. Be deliberate: removal from the list is slow, so only preload a domain you're certain will stay HTTPS-only forever.
Setting the header
# nginx — only over HTTPS
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# Apache
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" env=HTTPS
Note the env=HTTPS guard on Apache — never send HSTS over plain HTTP; the spec says browsers ignore it there, and it can cause confusion.
Verify
Re-run your audit. A pass means HSTS is present with a strong max-age. If you see a warning about a short max-age, bump it up once you're confident the rollout is stable.
More guides
How to Fix a Missing Content-Security-Policy Header
A missing CSP is the most common high-impact gap we find. Here's how to add one safely without breaking your site.
Securing Cookies — HttpOnly, Secure, and SameSite Explained
Three small flags turn a leaky cookie into a hardened one. Here's what Secure, HttpOnly and SameSite do and how to set them.