Learn · Topic explainer
What is HSTS? HTTP Strict Transport Security explained
HTTP Strict Transport Security (HSTS) is a one-line header that tells browsers "only ever load this site over HTTPS — even if someone types http:// or follows a stale plaintext link." It's effectively a defense against TLS downgrade attacks: once the browser has cached your HSTS policy, plaintext requests to your domain become impossible from that browser. This explainer covers how HSTS actually works, the bootstrap window that catches teams off-guard, and when preloading is — and isn't — the right call.
Why HSTS exists
An HTTPS site is only as secure as its first request. If a user types `example.com` (no scheme), the browser tries `http://example.com` first. Your server returns a 301 redirect to `https://example.com`. But on a hostile network, an attacker can intercept that initial HTTP request and serve their own content — including a fake login page that proxies the real site over TLS. The user sees the padlock, but only because the attacker is the one talking to the real server. HSTS closes this gap: once cached, the browser refuses to ever attempt http:// for that hostname again.
max-age and the bootstrap window
The `max-age` directive is the number of seconds the browser should remember the policy. A common starter value is `max-age=15552000` (six months); a hardened production value is `max-age=31536000` (one year). Until the browser receives the HSTS header at least once over HTTPS, it doesn't know to enforce — that gap is called the bootstrap window. Every first-time visitor on a new device has a bootstrap window, however brief. Preloading (covered below) is the only way to eliminate it entirely.
includeSubDomains: the subtle one
The `includeSubDomains` directive applies the HSTS policy to every subdomain of the listed host. If you set it on `example.com`, then `dev.example.com`, `staging.example.com`, and any other subdomain become HTTPS-only too. This is what you want — except when an internal team still runs a service on a subdomain that legitimately needs HTTP. Because HSTS is enforced by the browser cache, you can't easily roll back if a subdomain breaks. Wait until every subdomain is HTTPS-ready before adding `includeSubDomains`, and consider rolling out with a short max-age first.
Preload: powerful and one-way
The HSTS preload list is shipped with Chrome, Firefox, Safari, and Edge. Domains on the list have their HSTS policy enforced from the very first request — no bootstrap window, ever. The catch: removal takes weeks (browsers ship updates on their own schedule). To submit, your domain must serve HSTS with `max-age=31536000`, `includeSubDomains`, and the `preload` directive — and you submit at hstspreload.org. Preload is the right move for established domains where you're confident every subdomain is HTTPS-ready. It's a footgun on shared parent domains where a sister team might still need HTTP.
Where to set HSTS
HSTS is a single header, but you have four reasonable places to set it: (1) Your CDN (Cloudflare, CloudFront, Fastly) — the canonical choice if you have one. Headers ship for static assets, redirects, and routes that bypass your app server. (2) Your reverse proxy (nginx, Caddy) — fine if you self-host without a CDN. (3) Your application framework (Express + Helmet, Django SECURE_HSTS_SECONDS, Rails secure_headers) — works but ships only for routes that hit your app. (4) Multiple places at once — risky, because some browsers will see two headers and ignore both. Pick one layer.
Related Scorifya checks
Stack guides for hands-on rollout
Try the focused tools
Single-purpose checkers that test exactly what this topic covers.
See how your site scores
Run a free Scorifya scan on any URL you're allowed to test. The score breaks down across TLS, security headers, exposure, cookies, and DNS — exactly the areas this explainer covers.