HTTP Strict Transport Security (HSTS)
HTTP Strict Transport Security (HSTS) is a response header that tells browsers: “for the next N
seconds, only ever talk to this site over HTTPS.” After a browser has seen it once, it upgrades
every http:// link and typed address to https:// on its own, before any request leaves the
device.
Why it matters
Redirecting HTTP to HTTPS is not enough on its own. The very first request a visitor makes, for
example after typing example.com into the address bar, still goes out over plain HTTP. An attacker
on the same network (public Wi-Fi, a compromised router) can intercept that request and keep the
visitor on an insecure connection without them noticing. This is called an SSL-stripping or
downgrade attack.
HSTS closes that gap for every visit after the first one. With the preload directive and a listing
on the browser preload list, it closes it for the first visit too.
What we check
| Check | Passes when |
|---|---|
| HSTS present | Strict-Transport-Security is sent with max-age ≥ 15552000 (180 days) |
| HSTS covers subdomains | the header includes includeSubDomains |
| HSTS preload | the header includes preload |
A max-age below 180 days is reported as “needs attention”: it works, but protection lapses for
visitors who return less often than that.
How to fix
Send this header on every HTTPS response:
Strict-Transport-Security: max-age=31536000; includeSubDomains
31536000 seconds is one year. Only send it over HTTPS; browsers ignore it on plain HTTP.
Nginx
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Apache
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Cloudflare: SSL/TLS → Edge Certificates → HTTP Strict Transport Security (HSTS) → Enable.
Roll it out safely
HSTS is hard to undo: browsers remember it for the whole max-age. Before you turn it on:
- Make sure every page and every subdomain you plan to cover works over HTTPS.
- Start with a short
max-agesuch as300(five minutes), check that nothing breaks, then raise it to a week, then to a year. - Add
includeSubDomainsonly when all subdomains (including internal tools, mail web front ends and staging hosts) serve HTTPS.
Preloading
Browsers ship a built-in list of HSTS domains, so even a first visit is protected. To qualify, your
header must include max-age of at least one year, includeSubDomains and preload, and the bare
domain must redirect to HTTPS. Then submit the domain at hstspreload.org.
Preloading is a long-term commitment: removal from the list takes months to reach users’ browsers. Only preload once you are sure every subdomain will stay on HTTPS.