HTTP Strict Transport Security
HTTP Strict Transport Security (HSTS) is a security mechanism instructing browsers to interact with a site exclusively over HTTPS. Once a browser receives the Strict-Transport-Security header from a site over a secure connection, all future requests to the host are automatically upgraded to HTTPS for the duration specified by the policy.
Baseline: Widely available
Supported in all major browsers. webstatus.dev
Usage
HSTS exists to prevent protocol downgrade attacks. In a downgrade attack, an attacker intercepts a connection and forces a switch from HTTPS to plain HTTP. The victim's browser continues communicating without encryption, exposing Cookies, credentials, and session data to the attacker.
Without HSTS, a browser follows whatever protocol the
server or network dictates. A redirect
from
http:// to https:// creates a window of
vulnerability during the initial unencrypted request.
HSTS closes this window. After receiving the policy,
the browser converts all http:// requests for the
host to https:// internally before sending anything
over the network.
HSTS headers require HTTPS
Browsers process the
Strict-Transport-Security header only when
received over a secure HTTPS connection. The
header is ignored when sent over plain HTTP. This
prevents an attacker from injecting a false HSTS
policy through an unencrypted connection.
Trust on First Use
The relationship between browser and server relies
on the principle of Trust on First Use (TOFU). The
browser has no HSTS policy for a host until the first
successful HTTPS connection delivers the
Strict-Transport-Security header. This means the
initial visit remains vulnerable to a downgrade
attack if the user types http:// or follows an
unencrypted link.
HSTS preloading (described below) addresses the TOFU gap by embedding policies directly into the browser.
Directives
The Strict-Transport-Security header accepts three directives. Directives are not case-sensitive and appear in any order, but each directive appears only once.
max-age
Required. Specifies the number of seconds the browser
enforces the HSTS policy. Setting max-age=0
immediately deletes the stored policy, allowing HTTP
connections again.
Common values:
31536000: one year (365 days)63072000: two years (730 days)
includeSubDomains
Optional. No value. When present, the HSTS policy applies to all subdomains of the host in addition to the host itself. Every subdomain under the host must serve valid HTTPS for this directive to work correctly.
preload
Optional. No value. Signals the site meets the requirements for inclusion in browser HSTS preload lists. This directive is not part of the specification. Browsers introduced the preload mechanism independently.
Preloading
Browser vendors maintain a shared HSTS preload list compiled into the browser itself. Sites on this list enforce HTTPS from the first connection, eliminating the TOFU vulnerability.
When a user types a preloaded domain into the address bar, the browser generates a 307 Internal Redirect to the HTTPS version without making any HTTP request to the server. This browser-generated redirect acts like a 301 but happens locally in milliseconds, avoiding the 100+ ms round trip a server-side HTTP-to-HTTPS redirect requires. The page speed gain is the primary practical benefit of preloading beyond the security improvement.
Submitting for preloading
Submissions go through
hstspreload.org. The
recommended approach is to start with a short
max-age (e.g. max-age=300), monitor whether
any subdomains or services break, then gradually
increase to the required minimum before submitting.
After submission, the domain enters a pending
state. Propagation into stable browser releases
takes months.
The domain must satisfy all of the following at submission time and continuously afterward:
- Serve a valid TLS certificate
- Redirect all HTTP traffic to HTTPS on the same host (when listening on port 80)
- Serve all subdomains over HTTPS, including the
wwwsubdomain and any internal subdomains - Return a
Strict-Transport-Securityheader on the base domain over HTTPS with:max-ageof at least31536000(one year)includeSubDomainsdirectivepreloaddirective
- Persist the header through any additional redirects from the base domain
The recommended header value for submission:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Best practice is to serve the HSTS header with
every HTTPS response. With Apache, this is set
in the .htaccess file of the HTTPS root:
<IfModule mod_headers.c>
Header set Strict-Transport-Security
"max-age=63072000; includeSubDomains; preload"
</IfModule>
Preloading is difficult to reverse
Removing a domain from the preload list takes
months to propagate through browser release
cycles. Even after removal, users on older
browser versions still carry the preloaded
entry until they update. Preloading applies to
all subdomains and nested subdomains, including
internal-only hosts. Confirm every subdomain
supports HTTPS before submitting. Removing the
preload directive from the header makes the
domain eligible for removal, but the process
is slow and the long tail of outdated browsers
extends the effective commitment.
Preloaded top-level domains
Several TLDs are preloaded at the TLD level,
including .dev and .app. All content served
under these TLDs must use HTTPS
regardless of individual domain settings.
Considerations
The includeSubDomains tradeoff
The includeSubDomains directive is required for
preloading and provides the strongest protection,
but applies HSTS to every subdomain under the host.
Any subdomain serving HTTP-only content becomes
unreachable. Internal tools, staging environments,
and services like OCSP or CRL distribution points
on subdomains all need valid HTTPS before enabling
includeSubDomains.
Without includeSubDomains, domain Cookies
set without the Secure flag remain vulnerable
to attacker-controlled subdomains the user has
not previously visited.
Denial of service through HSTS injection
An attacker with the ability to inject HTTP response headers (through response splitting or a compromised proxy) forces HSTS policy adoption on a host serving only HTTP. The browser then refuses all plaintext connections to the host, creating a denial of service for the legitimate site.
Non-browser clients
The specification targets browser user agents. APIs, command-line tools, and HTTP libraries have no standardized HSTS handling. Applications relying on programmatic HTTP clients enforce transport security through their own configuration rather than HSTS headers.
Network time dependency
HSTS policy expiration relies on the client clock. Active network attacks subverting NTP or other time protocols extend or shorten the effective policy duration. Clients without a reliable real time clock are more susceptible.
Limitations
HSTS protects against protocol downgrade attacks and cookie hijacking over unencrypted connections. The mechanism does not protect against:
- Vulnerabilities in the TLS protocol itself
- Compromised servers (a secure transport layer does not help when the server is under attacker control)
- DNS-based attacks using fabricated domain names absent from the preload list
- Attacks during the TOFU window (addressed by preloading)
- Phishing attacks using unrelated domain names
- Mixed content loaded from third-party HTTP origins embedded in an HTTPS page
Example
A server responding over HTTPS includes the HSTS header to enforce secure connections for one year across all subdomains, with preload eligibility.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
The browser stores this policy and converts all
future http:// requests for the domain (and its
subdomains) to https:// for 31,536,000 seconds
(one year). Each HTTPS response refreshes the timer.
A server disabling HSTS sends a zero max-age:
Strict-Transport-Security: max-age=0
The browser deletes the stored policy immediately and no longer forces HTTPS.
SEO and HSTS
Googlebot follows HSTS policies. A properly
configured HSTS header with preload confirms
to crawlers the Canonical protocol is HTTPS,
reducing unnecessary HTTP-to-HTTPS redirect hops
during crawling.
Takeaway
HSTS forces browsers to communicate with a site
exclusively over HTTPS, preventing protocol
downgrade attacks and cookie hijacking.
The Strict-Transport-Security header sets the
policy duration and scope. HSTS preloading eliminates
the Trust on First Use vulnerability by embedding
the policy directly into the browser before the first
connection.
See also
- RFC 6797: HTTP Strict Transport Security
- HSTS Preload List Submission
- Strict-Transport-Security
- HTTPS
- Cookies
- Redirects
- HTTP headers