HTTP Strict Transport Security (HSTS) is a policy a site declares with one response header, and a browser then enforces for every later visit. The server sends the header over HTTPS, and the browser stores it as a rule about that host.
The header has one required directive and one optional one. max-age is the number of seconds the policy stays in effect. includeSubDomains is a valueless flag that extends the policy to every subdomain of the host, so a rule set on example.com also covers api.example.com and login.example.com. The two combine in forms like Strict-Transport-Security: max-age=31536000; includeSubDomains, a one-year policy for the whole domain tree.
What the browser does with that rule is the point. Before dereferencing any http URI to a Known HSTS Host, it rewrites the URI to https (RFC 6797 §8.3). And if the TLS handshake produces any error or warning, the browser terminates the connection: the spec says the UA must terminate if there are any errors, whether “warning” or “fatal” or any other level (§8.4), and that this should be done with no user recourse, presenting no dialog offering the user a way to proceed (§12.1). That is what separates HSTS from an ordinary redirect: a redirect still requires the user to first reach the server over plain HTTP, where an attacker can intercept. HSTS moves the decision into the browser, where it happens before any insecure request leaves the machine.
The header only has force when it arrives over secure transport. The server-side rule is that an HSTS Host must not include the header in a response sent over plain HTTP (RFC 6797 §7.2), and the user-agent rule is the stronger guard: if a response is received over insecure transport, the UA must ignore any Strict-Transport-Security header field present in it (§8.1). So an attacker who strips TLS cannot simply forge the header and rewrite the browser’s policy, because the browser is required to discard any header that arrives unencrypted.
Two practical details are easy to miss. Setting max-age=0 is the way to withdraw a policy: it tells the browser to delete the rule, including any asserted subdomain coverage. And a site should not advertise a huge max-age until it is certain every subdomain can actually serve HTTPS, because a broken subdomain under an includeSubDomains rule becomes unreachable, not merely slow.
HSTS has a known first-visit gap. The very first visit cannot be protected, because the browser has not yet received the header, so an attacker who intercepts that first request wins. The spec describes a client-side pre-loaded list of Known HSTS Hosts as a way to help protect against this bootstrap gap (RFC 6797 §12.3).

The Campfire
CommentsThanks. Your comment is waiting for the desk. Once it is approved it appears here within about a minute.
Add a comment