Glossary

HSTS (HTTP Strict Transport Security)

Last verified

Definition

HSTS is an HTTP response header that tells browsers to reach a site only over HTTPS for a set period and to refuse to bypass certificate errors there.

HTTP Strict Transport Security is defined in RFC 6797. When a browser receives the Strict-Transport-Security header over a valid HTTPS connection, it records the host as an HSTS host for max-age seconds. During that time it rewrites every http:// URL for that host to https:// before sending anything, and treats certificate errors as fatal, with no option to proceed anyway. The header is ignored when it arrives over plain HTTP.

Why it matters

A server-side redirect from HTTP to HTTPS still leaves the first plaintext request exposed, which is exactly what SSL stripping exploits. HSTS removes that request on every visit after the first, and turns a man-in-the-middle with an invalid certificate into a hard failure instead of a warning users click through. The includeSubDomains directive extends the policy to every subdomain, which is powerful but breaks any subdomain that still serves only HTTP. To protect the very first visit, the domain has to be on the HSTS preload list.

Example

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
curl -sI https://example.com | grep -i strict-transport-security

Start with a short max-age such as 300 while you confirm every subdomain works over HTTPS, then raise it. In Chrome DevTools an HSTS upgrade shows up as a 307 Internal Redirect that never reaches the network.

Common misconceptions

  • HSTS protects the very first visit. Without preloading, the browser has not seen the header yet, so the first request can still be intercepted.
  • Sending the header on the HTTP response is enough. Browsers ignore it over HTTP; it must arrive over HTTPS with a valid certificate.
  • HSTS pins certificates like HPKP did. HSTS only forces HTTPS and does not care which certificate you use. HPKP, which did pin keys, was removed from Chrome in Chrome 72.

See also