missing-hsts
HSTS not enabled
HSTS tells browsers "always use HTTPS for this domain, never plain HTTP". Without it, the very first connection a visitor makes is unprotected and an attacker can keep them on the unsecured version indefinitely.
What this means in plain English
HSTS is a small instruction your website sends to browsers that says “this domain is HTTPS only — never use plain HTTP, even if the visitor types it, even if some server tries to redirect you back”. Once a browser has seen this instruction, it remembers it for as long as the instruction specifies, and refuses to fall back to the unsecured version.
Your site doesn’t currently send this instruction. You may have HTTPS set up correctly, and your server may even redirect plain HTTP to HTTPS — but without HSTS, the very first connection a visitor makes can still be plain HTTP.
Why it matters to your business
Even with HTTPS in place, the first request a fresh browser sends
to your domain is plain HTTP if the visitor typed the address
without https://. An attacker on the network — for example on a
public Wi-Fi — can intercept that one unencrypted request, never let
it reach your server, and serve a fake version of your site instead.
HSTS closes that window. The first time a visitor arrives over HTTPS, their browser locks in the instruction and never tries plain HTTP for your domain again.
There’s still a single remaining gap: the very first visit ever, before the browser has seen the instruction. That gap can be closed by submitting your domain to the HSTS preload list, which is hard-coded into every major browser. After preload, even a brand-new browser refuses plain HTTP for your domain from the very first attempt.
How to fix it
Whoever runs your web server adds a single line to the response configuration. The standard text:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
Three parts:
max-age=63072000is two years in seconds — the minimum required to qualify for the preload list.includeSubDomainsextends the protection to all your subdomains (shop.your-domain.example,mail.your-domain.example, etc.). Only enable this once you’re certain every subdomain is HTTPS-only.preloadsignals you intend to be added to the browser preload list.
Common server configuration:
nginx:
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
Apache:
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Caddy:
header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
Once it’s been live and stable for a few weeks, submit the domain to hstspreload.org for inclusion in the browser preload list. The submission is hard to reverse — only do it when you’re confident every host under your domain serves HTTPS correctly.
A small rollout caution: starting at the full two-year value on day
one and discovering an HTTP-only subdomain afterwards (a forgotten
internal staging server, for example) means visitors won’t be able
to reach it for two years. The safer path is to start with a much
shorter value (max-age=300 for a few days, then max-age=86400
for a week, then the full two years), giving you time to discover
any straggler subdomains.
Further reading
- hstspreload.org — the preload-list submission portal.
- OWASP HSTS Cheat Sheet
- RFC 6797 — HSTS specification