HTTP Strict Transport Security (HSTS)
debt(d5/e3/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list owasp-zap, ssllabs, and lighthouse — all specialist/external scanning tools. Missing or misconfigured HSTS headers won't be caught by a compiler or default linter; you need to run a dedicated security scanner or audit tool against a live HTTPS endpoint.
Closest to 'simple parameterised fix' (e3). The quick_fix is essentially a one-liner header addition (Strict-Transport-Security: max-age=31536000; includeSubDomains), but correctly deploying it requires verifying all subdomains support HTTPS, ensuring the header only appears on HTTPS responses, and optionally submitting to the preload list — making it slightly more than a pure single-line patch but still well within one component.
Closest to 'localised tax' (b3). The applies_to scope is web contexts only, and the burden is mostly a configuration/header-emission concern. Once correctly configured at the server or middleware layer, the rest of the codebase is largely unaffected. There is some ongoing discipline required (subdomains, load-balancer TLS termination), but it doesn't reshape every future change.
Closest to 'serious trap' (t7). The misconception field states that developers believe HSTS protects users on their first visit, but the Trust On First Use problem means the very first HTTP request is still unprotected. This directly contradicts the implied guarantee of the feature name ('strict transport security'), mirrors a misunderstanding common even among experienced developers, and requires understanding HSTS preloading to fully resolve — a non-obvious secondary mechanism.
Also Known As
TL;DR
Explanation
HSTS (RFC 6797) is delivered via the Strict-Transport-Security header: Strict-Transport-Security: max-age=31536000; includeSubDomains; preload. Once received, the browser refuses plain HTTP connections to that domain for the max-age duration — even if the user types http://. This eliminates SSL stripping and downgrade attacks at the browser level. The preload directive submits the domain to browser vendor hardcoded lists (hstspreload.org). In PHP, emit the header on all HTTPS responses: header('Strict-Transport-Security: max-age=31536000; includeSubDomains').
Common Misconception
Why It Matters
Common Mistakes
- Setting a very short max-age (e.g. 60 seconds) that effectively disables the protection.
- Not including includeSubDomains when subdomains are also served over HTTPS.
- Setting HSTS on a response served over plain HTTP — browsers ignore it.
- Sending HSTS from behind a load balancer that terminates TLS, ensuring the header only appears on HTTPS responses.
Code Examples
// Only setting HSTS on login page — leaves other pages vulnerable to stripping
header('Strict-Transport-Security: max-age=31536000; includeSubDomains'); // on ALL pages