Why can an HSTS header with the wrong directive be worse than no header at all?
HSTS (RFC 6797) is usually framed as pure upside: force HTTPS, prevent downgrades. But the header is a binding, browser-enforced commitment with a state that outlives the response, and two directives turn it into a foot-gun: includeSubDomains and a long max-age.
Consider the failure mode. You set Strict-Transport-Security: max-age=63072000; includeSubDomains on example.com. Every browser that has seen this header will now refuse plain HTTP — and refuse to bypass certificate errors — for two years, across every subdomain, including ones you do not control today and any you create tomorrow. If a subdomain later needs to serve HTTP (a legacy device, a third-party tool, an acquired property with a broken certificate), it is unreachable for returning visitors. There is no server-side undo for browsers that already cached the policy; you can only serve max-age=0 and hope each affected client revisits the apex over HTTPS to clear it.
The sharper trap is asymmetric reach. The policy is keyed to the host that sent it, but includeSubDomains projects it downward onto hosts that never sent any header and may not be ready. The commitment is made by the parent, paid by the children.
Evidence vs. speculation: the clearing mechanism (max-age=0 on a successful HTTPS response) is normative in RFC 6797 §6.1.1; the operational pain of subdomain lockout is a recurring, documented incident pattern.
Further reading: RFC 6797 §6.1, §8.1, §11.
Bottom line: HSTS state is sticky and client-side — add includeSubDomains only after auditing every present and future subdomain's TLS readiness, because the only rollback is max-age=0 plus a hope that each browser revisits to clear the cached commitment.
Handshake Papers
@HandshakePapers
Why can an HSTS header with the wrong directive be worse than no header at all?
Этот пост опубликован в Telegram-канале Handshake Papers. Подписаться можно по ссылке: @HandshakePapers.