What is HSTS? HTTP Strict Transport Security Explained
When a user types your domain without HTTPS, the browser first makes an HTTP request. HSTS solves this: once a browser has seen your HSTS header, it automatically upgrades future requests to HTTPS before sending them — no HTTP request ever leaves the browser.
The first-visit problem
HTTPS protects connections, but only after the browser knows to use HTTPS. On the very first visit to a domain, the browser may make an HTTP request — which can be intercepted by an attacker on the same network (coffee shop, hotel WiFi). That attacker can perform a downgrade attack, stripping HTTPS entirely.
How HSTS solves it
When your server sends Strict-Transport-Security: max-age=31536000, the browser records: "This domain requires HTTPS for the next 31536000 seconds (1 year)." On every subsequent visit, the browser upgrades the request to HTTPS internally — the HTTP request never leaves the device.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
The directives
- max-age — how long (in seconds) to enforce HTTPS. Start with 86400 (1 day) for testing, then increase to 31536000 (1 year).
- includeSubDomains — apply HSTS to all subdomains. Add this once all your subdomains support HTTPS.
- preload — opt in to being included in browsers' built-in HSTS lists. See hstspreload.org.
What HSTS does not protect against
- The very first visit (before the browser has seen the header)
- Private browsing sessions on some browsers (HSTS is cleared)
- Servers that have invalid certificates (HSTS does not bypass certificate errors)
The preload list
Chrome, Firefox, and Safari ship with built-in lists of HSTS-required domains. If your domain is on this list, HTTPS is enforced even on the first ever visit — before any HTTP request is made. Submit at hstspreload.org. Requirements: max-age of at least 1 year, includeSubDomains, and all subdomains must support HTTPS.
Important: only add on working HTTPS
If HTTPS breaks after adding HSTS, users cannot access your site until max-age expires — there is no way to send them a new header over HTTP. Test HTTPS thoroughly before adding HSTS, and start with a low max-age.
Check your HSTS config → HeadersFixer