Missing HTTP Strict Transport Security
CWE-319CWE-523OWASP A02:2021Updated September 4, 20265 min read
HTTP Strict Transport Security instructs the browser to reach a site over HTTPS only. If the header is missing, or its lifetime is set to a few days, an attacker on the same network can force the first request back to HTTP and intercept or alter the traffic before encryption ever begins.
Virtually every site runs on HTTPS these days, and yet a browser visit still begins with an unencrypted request remarkably often. Someone types an address without a protocol, clicks an old link, or follows a bookmark from years ago. That single first request is exactly what an attacker waits for. This article covers how HSTS closes that window, and which settings go wrong.
What is HTTP Strict Transport Security?
HTTP Strict Transport Security (HSTS) is an HTTP header with which a server instructs the browser to reach this domain over HTTPS only from now on. The browser remembers that instruction for the given period and from then on converts every http:// address for this domain to https://, before a single byte goes onto the network.
The difference from an ordinary redirect is subtle but decisive. A redirect is a response from the server: the browser therefore has to send an unencrypted request in order to hear that it should switch to HTTPS. HSTS is an instruction the browser remembers: no unencrypted request is sent to find out that it should not have been allowed.
Picture a reception desk where visitors have to show their passport. A redirect is the receptionist saying: “you are inside now, but please walk back and check in properly.” HSTS is the sign outside that visitors had already read before they walked in. In the first case, someone has already stood in the hall; in the second, they have not.
How does a downgrade attack work?
The attack takes place on the network: a public wifi network, a compromised router, or an intermediate provider. The attacker does not have to break encryption, only prevent it from ever being established.
Vulnerable:
HTTP/1.1 301 Moved Permanently
Location: https://portal.example/login
On the face of it this is correct: the server neatly forwards visitors to HTTPS. The problem is that in order to receive this response, the user first had to send the following:
GET /login HTTP/1.1
Host: portal.example
That request travels across the network in readable form. An attacker sitting in between never lets the redirect arrive. Instead they maintain the connection with the user over HTTP themselves, speak HTTPS with your server at the back, and read along with everything the victim types: username, password, session cookie. The user sees a working login page and at most notices that the padlock is missing.
Safe:
HTTP/1.1 200 OK
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
After one successful HTTPS visit the browser remembers this for a year. If the user then types portal.example in the address bar, the browser sends an HTTPS request straight away; there is no unencrypted request left to intercept. includeSubDomains extends that rule to every subdomain, which matters because a forgotten test.portal.example would otherwise remain an open side door. With preload the domain joins a list included in the browser itself, so even the very first visit is protected.
includeSubDomains once you are certain that every subdomain supports HTTPS, including internal test environments and supplier systems. A subdomain that only runs HTTP becomes unreachable for all visitors after this setting, and the browser remembers that for the full lifetime.What is the impact of missing HSTS?
The severity is usually rated low to medium, because the attacker needs a position in the network path. That condition is less demanding than it sounds: a public network on a train, in a hotel or a café, a spoofed wifi access point, or a compromised home device will do.
If the attack succeeds, the damage is complete. The attacker reads everything that crosses the connection: credentials, session cookies, personal data and the contents of forms. They can also alter the response, which opens the way to a fake login screen or injected script code. Because the session cookie is captured in that scenario, the attacker does not even need to know the password to continue.
A max-age that is too short weakens the protection without removing it entirely. If the value is 30 days, a user who has not visited for six weeks is vulnerable again on their next visit, which is precisely the moment they type the address once more.
How do you detect missing HSTS?
The check starts with the HTTPS response: is there a Strict-Transport-Security header, and if so, how long is the max-age? A value under a year is a point of attention, and a value of zero actively disables the protection.
Then comes the investigation that scanners usually skip. Is the header set on subdomains too, or does includeSubDomains cover domains that offer no HTTPS themselves? Does the HTTP version of the site forward correctly to HTTPS, and does it land on the right path? Is the header accidentally set only on the home page and not on the API or the login endpoint? And is the domain on the preload list while a subdomain without a certificate still exists? During a penetration test AssistSec checks the full certificate chain and redirect structure, and assesses whether any path remains along which a user can still speak to your application unencrypted.
How do you prevent missing HSTS?
- Send
Strict-Transport-Securityon every HTTPS response, withmax-age=31536000as a guide value. - Add
includeSubDomainsonce you are sure all subdomains support HTTPS. - Build up the lifetime in phases: start short, verify that everything works, then raise it to a year.
- Keep forwarding HTTP to HTTPS; HSTS complements that redirect rather than replacing it.
- Consider joining the preload list for domains that run permanently and fully on HTTPS.
- Never set the header on an unencrypted response; browsers ignore it there, which gives a false sense of security.
- Monitor the validity of your certificates actively, because with HSTS visitors can no longer click past a certificate error.
- Configure the header centrally in your web server or proxy, so new hosts and routes inherit it automatically.
Sources
Frequently asked questions
Is a redirect from HTTP to HTTPS not enough?
No, because that redirect itself travels unencrypted. An attacker between user and server can intercept that first request and replace the response, so the browser never arrives at the HTTPS version. The redirect is still needed, but HSTS is what stops an unencrypted request from being sent at all.
Which max-age should I set?
The common norm is 31536000 seconds, or one year. Shorter values such as 30 days occur regularly and are better than nothing, but they shrink the window in which the browser remembers the rule. When in doubt, build up: start with a few minutes, check that everything works, and raise it step by step to a year.
What does the preload option do?
With preload your domain joins a list baked into browsers themselves. The browser then knows before the very first visit that your site is reachable over HTTPS only, which protects the opening request too. Be careful: removal from that list takes months, so do this only if every subdomain supports HTTPS permanently.
Can HSTS make my site unreachable?
Yes, and that is the reason for a careful rollout. Once a browser has remembered the rule, it refuses every unencrypted connection for the remaining lifetime. If your certificate expires or a subdomain only serves HTTP, visitors cannot click past it. Test with a short max-age first.
Related articles
- VulnerabilitiesCWE-327A02:2021Cryptographic failuresCryptographic failures explained: MD5 for passwords, ECB mode, hardcoded IVs and home-grown crypto, and why Argon2id and AES-GCM are the fix.
- VulnerabilitiesCWE-319A02:2021Insecure transport and weak TLSInsecure transport explained: plain HTTP, missing HSTS, outdated TLS versions and cookies without Secure, and how to enforce HTTPS everywhere.
- VulnerabilitiesCWE-16A05:2021Security misconfigurationSecurity misconfiguration explained: how default passwords, debug modes and open cloud buckets let attackers in, and how to harden your systems.
- VulnerabilitiesCWE-1004A07:2021Unprotected authentication cookieA session cookie without HttpOnly, Secure and SameSite is readable, interceptable and abusable. Learn what each attribute actually covers.