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:

  1. Serve a valid TLS certificate
  2. Redirect all HTTP traffic to HTTPS on the same host (when listening on port 80)
  3. Serve all subdomains over HTTPS, including the www subdomain and any internal subdomains
  4. Return a Strict-Transport-Security header on the base domain over HTTPS with:
    • max-age of at least 31536000 (one year)
    • includeSubDomains directive
    • preload directive
  5. 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

Last updated: March 6, 2026