What is HSTS
Key Takeaways
- HSTS eliminates the HTTP→HTTPS redirect window where an attacker can intercept the plaintext request
- Once a browser sees the HSTS header, it converts all HTTP requests to HTTPS internally — no network request to port 80
- HSTS preload list hardcodes your domain into browsers — but it's nearly impossible to undo once submitted
- Misconfigured HSTS with a broken certificate locks users out completely — there's no 'proceed anyway' option
HTTP Strict Transport Security (HSTS) is a response header that instructs browsers to only communicate with a domain over HTTPS. Once a browser receives the Strict-Transport-Security header, it internally rewrites all future HTTP requests to that domain as HTTPS — before any network request is made. This eliminates the vulnerability window during the initial HTTP-to-HTTPS redirect, where an attacker on the network could intercept or modify the plaintext request.
Why it matters
- Eliminates SSL stripping — without HSTS, an attacker performing a man-in-the-middle can intercept the initial HTTP request and prevent the redirect to HTTPS. The user stays on HTTP without knowing. HSTS makes this impossible after the first visit.
- No redirect latency — the browser converts
http://tohttps://internally (307 Internal Redirect). No network round trip to the server for a 301/302 redirect. Faster and more secure. - Prevents mixed content accidents — if application code accidentally generates an
http://link to the same domain, the browser upgrades it to HTTPS automatically. No mixed content warning, no insecure request. - Cookie protection — without HSTS, cookies set without the
Secureflag can be sent over HTTP. HSTS ensures the browser never makes an HTTP connection, so cookies are never exposed on the wire. - Preload for first-visit protection — the HSTS preload list (hardcoded in Chrome, Firefox, Safari, Edge) protects even the very first visit to a domain. Without preload, the first request is still vulnerable until the browser receives the header.
How it works
- User visits
https://example.com— the server responds with the HSTS header - Browser stores the policy — records that
example.comrequires HTTPS for the specifiedmax-ageduration - Subsequent visits — if the user types
http://example.comor clicks an HTTP link, the browser internally redirects to HTTPS (307 Internal Redirect) without making any HTTP request - Certificate errors become fatal — with HSTS active, the browser will NOT show a “proceed anyway” option for certificate errors. Invalid cert = completely blocked.
- Policy renewal — each HTTPS response with the header resets the
max-agetimer. If the header disappears, the policy expires after the lastmax-ageduration.
In real systems
Nginx — basic HSTS:
server {
listen 443 ssl;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# max-age=31536000 = 1 year
# includeSubDomains = applies to all subdomains
# always = send header even on error responses
}
Progressive rollout (recommended):
# Start with 5 minutes to test
add_header Strict-Transport-Security "max-age=300" always;
# After confirming HTTPS works everywhere, increase to 1 week
add_header Strict-Transport-Security "max-age=604800; includeSubDomains" always;
# After full validation, set to 1 year + preload
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
HSTS preload submission:
Requirements for hstspreload.org:
- Serve a valid certificate
- Redirect HTTP to HTTPS on the same host
- Serve the HSTS header on the HTTPS response with:
max-ageof at least 31536000 (1 year)includeSubDomainsdirectivepreloaddirective
- All subdomains must support HTTPS
AWS CloudFront — add HSTS via a response headers policy:
{
"StrictTransportSecurity": {
"Override": true,
"AccessControlMaxAgeSec": 31536000,
"IncludeSubdomains": true,
"Preload": true
}
}
Where it breaks
HSTS with broken certificate — you enable HSTS with max-age=31536000, then your certificate expires or is misconfigured. Normally, users can click “Advanced → Proceed” to bypass certificate warnings. With HSTS active, browsers show a hard error with no bypass option. Users are completely locked out until you fix the certificate. If you’re on the preload list, even clearing browser data doesn’t help — the policy is hardcoded in the browser binary.
includeSubDomains breaks internal services — you add includeSubDomains to example.com, but internal.example.com runs on HTTP (legacy admin panel, development server, or IoT device interface). The browser now refuses to load it over HTTP. Every subdomain must have valid HTTPS before enabling includeSubDomains. Audit all subdomains first.
Preload list removal takes months — you submit your domain to the HSTS preload list, then discover a subdomain that can’t support HTTPS. Removing from the preload list requires submitting a removal request, waiting for it to be processed, waiting for the next browser release cycle, and waiting for users to update their browsers. This can take 6-12 months. During that time, the affected subdomain is unreachable for users with updated browsers.
Operational insight
HSTS creates an implicit dependency on your certificate infrastructure’s reliability. Without HSTS, a certificate failure degrades the experience (warning page) but users can proceed. With HSTS, a certificate failure is a complete outage with no workaround. This means HSTS should only be enabled after you have automated certificate renewal (ACME/CLM), certificate monitoring with alerting well before expiry, and confidence that every subdomain (if using includeSubDomains) has valid HTTPS. Enable HSTS last — after your certificate automation is proven reliable, not before.
Related topics
Ready to Secure Your Enterprise?
Experience how our cryptographic solutions simplify, centralize, and automate identity management for your entire organization.