The default behavior when a user types a bare hostname into a browser is to attempt HTTP. The site's web server responds with a 301 or 302 redirect to the HTTPS version. The browser follows the redirect, completes a TLS handshake, and the rest of the session is encrypted.
Between "user types domain" and "TLS handshake completes" there's a window — usually a few hundred milliseconds — where the request and the redirect travel in cleartext. An attacker on the network path can intercept that first HTTP request, return a fake response, and either serve a malicious page directly or strip the redirect's https:// and proxy the session through a transparent HTTP-to-HTTPS gateway under their control. The user sees a working site. The address bar shows the right domain. The connection is not encrypted.
This attack class is called SSL stripping, demonstrated convincingly by Moxie Marlinspike at Black Hat 2009. The tools to do it (sslstrip and its descendants) are still publicly available and still work against any site that allows an HTTP-first connection.
HSTS: A Promise the Browser Remembers
HTTP Strict Transport Security (RFC 6797, 2012) is a response header a site sends over HTTPS that tells the browser: "for the next N seconds, never connect to me over HTTP. Upgrade everything to HTTPS at the browser level, before any request leaves the device."
A complete HSTS header looks like this:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
The three directives:
- max-age — how many seconds to remember the policy. 63072000 is two years; this is the typical floor for serious deployments.
- includeSubDomains — apply the same policy to every subdomain of the host. This is the lever that turns HSTS from "this hostname" into "this whole namespace."
- preload — signals consent for the domain to be added to the browser-shipped preload list. Without this directive, the browser won't accept your domain into the list.
Once a browser has seen this header on a successful HTTPS visit, it caches the policy. Future attempts to navigate to http://example.com are upgraded to https://example.com internally — the HTTP request never leaves the device.
The Bootstrap Problem
HSTS works perfectly after the first successful HTTPS visit. The first visit is the issue. If a user has never been to your site, or if they've cleared browser data, or if they're on a fresh device, the browser has no HSTS cache for your domain. The first request goes out over HTTP, and SSL stripping is back on the table.
The HSTS preload list is the answer. It's a list of domains that browsers consider HSTS-enabled before any first visit, shipped as a static asset in the browser itself.
Chrome maintains the canonical list at hstspreload.org. Firefox, Safari, Edge, and Brave all consume the same list (with minor curation differences). It ships hardcoded inside the browser binary and updates with each browser release.
To get on it, a domain must meet a checklist:
- Serve a valid certificate.
- Redirect from HTTP to HTTPS, on the same hostname (no cross-hostname redirects in the upgrade path).
- Serve all subdomains over HTTPS, including
www.. - Serve the HSTS header on the base domain over HTTPS with
max-age≥ 31536000 (1 year),includeSubDomains, andpreload. - Submit the domain at hstspreload.org for review.
Approval typically takes weeks to months, after which the domain appears in the next browser release. The list contains around 150,000 domains as of 2026 — banks, governments, major SaaS providers, and a long tail of security-conscious sites.
The One-Way Door
Here's the catch. Removing yourself from the preload list is much slower than getting added. The removal process at hstspreload.org takes weeks of review, and even after Chrome removes you, the older browser builds in the field still have your domain hardcoded. Users on those builds will continue refusing HTTP connections to your domain for as long as that browser version is running.
In practice, this means:
- If you preload
example.comwithincludeSubDomains, every subdomain — includingintranet.example.com,legacy-app.example.com, anything you haven't yet HTTPS-enabled — will become unreachable to preloaded browsers. - If you let your TLS certificate expire on a preloaded domain, users see a hard browser-level error with no "proceed anyway" button. (This is intentional and is actually a HSTS feature, not a bug.)
- If you decide HTTPS is too expensive or your CA relationship breaks down, you cannot fall back to HTTP for at least a couple of browser release cycles.
For most modern sites this is fine — HTTPS is no longer optional and certificates are free via Let's Encrypt. But it explains why preloading is an explicit opt-in, not the default for every site that ships an HSTS header.
What HSTS Does Not Do
| Threat | HSTS coverage |
|---|---|
| SSL stripping on first visit (no preload) | Not covered |
| SSL stripping on subsequent visits | Blocked |
| SSL stripping on first visit (preloaded) | Blocked |
| Forged certificate from rogue CA | Not covered (use cert pinning or CT) |
| User clicking "proceed despite cert warning" | No proceed option on preloaded sites |
| Compromised endpoint | Not covered |
HSTS solves one specific attack: the cleartext-first-byte window. It does nothing about whether the TLS certificate the browser eventually validates is the right one. For that you need separate mechanisms — certificate pinning for hardcoded trust, CAA records to limit which CAs can issue for your domain, and CT logs for detecting issuance you didn't authorize.
Practical Deployment
For a site that's confident in its HTTPS posture and wants the strongest protection: deploy HSTS in stages.
- Start with a short max-age (300 seconds) and no
includeSubDomains. Verify nothing breaks for a week. - Increase to
max-age=86400(1 day) for a couple of weeks. - Add
includeSubDomainsonly after auditing every subdomain to confirm HTTPS works on each. - Increase to
max-age=31536000(1 year) for a month or two. - If everything is stable, add
preloadand submit to hstspreload.org.
The progression matters because each step is harder to undo than the one before it. The preload submission is the final stop on a one-way road. Most issues that would break a preloaded deployment will show up in the earlier stages while the cache TTL is short enough to recover from.
For a deeper view of related transport hardening, see our pieces on TLS 1.3 and Certificate Transparency.