Skip to main content

HSTS

High

HTTP Strict Transport Security

HSTS tells browsers to only connect to your site over HTTPS, never HTTP. Once a browser sees the Strict-Transport-Security header, it refuses to make unencrypted connections to that domain for the duration of max-age. The HSTS preload list extends this to first-time visitors.

Overview

HSTS addresses the sslstrip vulnerability: when a user types example.com in their browser, the browser first makes an HTTP request before being redirected to HTTPS. A MITM attacker can intercept this initial HTTP request and serve a downgraded HTTP page transparently.

With HSTS, the browser internally upgrades all HTTP requests to HTTPS after the first successful HTTPS response with the HSTS header. The policy is stored with a max-age (seconds). The includeSubDomains directive extends HSTS to all subdomains. The preload directive makes the site eligible for inclusion in browser preload lists, eliminating the first-visit window entirely.

HSTS preloading is a commitment: once your domain is on the preload list, removing it takes weeks and browsers will block HTTP connections to your domain even without a server response. Only preload domains you are certain will always serve HTTPS.

The Attack: SSL Stripping (sslstrip attack)

An attacker performs a MITM attack on the initial HTTP connection before the HTTPS redirect. Without HSTS, the browser never knows HTTPS was expected.

Without HSTS – vulnerable to sslstrip
http
# User types: example.com (browser starts with HTTP)
GET http://example.com/ HTTP/1.1   ← attacker intercepts this

# Attacker serves HTTP page to user
# User never gets the HTTPS redirect
# Attacker reads all traffic in cleartext

Defenses

1Set Strict-Transport-Security with long max-age

The standard HSTS deployment. max-age=31536000 is 1 year. includeSubDomains protects all subdomains. Add this header to every HTTPS response.

Standard HSTS header
http
Strict-Transport-Security: max-age=31536000; includeSubDomains

2HSTS preload

Adding the preload directive and submitting to hstspreload.org puts your domain on Chrome, Firefox, Safari, and Edge's preload lists. Browsers ship with this list – no first-visit HTTP request is ever made. Requirements: HTTPS on root domain and all subdomains, 1-year max-age minimum, includeSubDomains.

HSTS header with preload
http
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload

Checklist

  • Set Strict-Transport-Security on all HTTPS responses – not just the homepage
  • Use max-age of at least 1 year (31536000 seconds)
  • Add includeSubDomains if all subdomains serve HTTPS
  • Redirect HTTP to HTTPS at the server level before HSTS can help
  • Submit to hstspreload.org only after all subdomains have valid HTTPS
  • Do not set HSTS on HTTP responses – it is ignored and wastes bytes

Related Headers

Related Status Codes

FAQ

Should I include the preload directive?

Only if you are certain every subdomain now and in the future will serve HTTPS. Preloading is difficult to reverse – it takes months to be removed from browser preload lists and users will see connection errors for HTTP subdomains during that time. For most sites, max-age + includeSubDomains without preload is the right choice.

Does HSTS protect against all MITM attacks?

No. HSTS prevents protocol downgrade (HTTP interception). It does not protect against attackers with a trusted CA certificate, BGP hijacking, or attacks on the TLS implementation itself. HSTS is one layer of a defense-in-depth strategy.