After a security review, an administrator enabled HSTS on the company's main domain with the option that includes all subdomains, and a long expiry. It was the textbook recommendation, and it came straight from the report: serve the site over HTTPS only, and tell browsers to remember that.
An internal tool lived on a subdomain that only supported plain HTTP. Browsers that had visited the main site now refused to load it over anything but HTTPS, and there was no way to click through the warning. Staff lost access to the tool until it was fixed.
Because the setting was cached in browsers for a year, the fix required putting a valid certificate on the internal tool rather than just removing the header. This is a composite of cases from a mid-sized services firm and a few others like it, and the sequence is the usual one: a sound change, a forgotten corner, and a setting that cannot be taken back quickly.
What HSTS does
HTTP Strict Transport Security is a header that a site sends over HTTPS. It tells the browser: for this host, and for a stated period, do not use plain HTTP at all. If someone types http:// or follows an old link, the browser rewrites the address to HTTPS itself, before any network request is made. It also changes how certificate errors behave. Without HSTS, a browser shows a warning for a bad certificate and lets the user click through. With HSTS, that option is removed.
A typical header looks like this:
Strict-Transport-Security: max-age=31536000; includeSubDomains
The number is the lifetime in seconds, here one year. The includeSubDomains directive extends the rule to every name beneath the domain: www.example.com, intranet.example.com, and any subdomain that anyone has created, forgotten or is yet to create. The browser stores this in its own database and applies it whether or not the site is reachable at that moment.
This is a useful protection. It stops downgrade attacks and cookie theft on shared networks. The administrator was right to want it. The mistake lay in the scope and in the speed, not in the idea.
The change, and the first complaint
The security review had found that the main site sometimes loaded over HTTP and recommended HSTS with the usual long lifetime. The administrator added the header in the web server configuration for the main domain, tested the public site, saw the header in curl -I and closed the ticket.
The first complaint arrived the next morning from the finance team. The internal tool, an old reporting dashboard on intranet.example.com, would not open. The browser showed a connection error or a certificate error with no option to proceed. A colleague with a new laptop could open it without trouble. A contractor on a personal machine could too.
That pattern misled people. A tool that works for some and not for others suggests a permissions problem, a VPN issue or a faulty network switch, and the first two hours went on exactly those. The real difference was simple: the people affected had visited the main site since the change, so their browsers had stored the rule, and the others had not.
Why it could not be undone with a click
The administrator's first instinct was to remove the header. That was a reasonable move and it did nothing for anyone who already had it. A browser keeps the HSTS entry until its lifetime runs out, which here meant a year from the last time it saw the header. Removing the header stops new visitors from storing the rule and does not clear the stored one.
Two partial remedies exist. Sending the header again with max-age=0 over HTTPS tells browsers that see it to forget the entry, but only the browsers that come back to the main site and receive it. And on a single machine you can delete the entry by hand from the browser's internal HSTS page. For a company with a few hundred laptops, neither was attractive, and the manual route is awkward when the entry belongs to the parent domain with includeSubDomains, because the rule covering the subdomain is the parent's.
There was also a political cost. The security team had asked for the change and the infrastructure team had made it, and the finance team, who could not run their month-end reports, did not much care whose idea it was. A rollback was proposed and rejected, because the main site now needed the header and the real defect was an HTTP-only tool that should never have been a dependency of anything important. The postmortem noted that the tool had been flagged in an earlier review and left alone because it still worked.
The fix: give the tool HTTPS
Since browsers would insist on HTTPS for the subdomain for up to a year, the quick way out was to make HTTPS work. The reporting dashboard ran on an old server that supported only port 80, so the administrator put a reverse proxy in front of it. The proxy held a valid certificate for intranet.example.com and passed requests to the tool over the internal network.
| Option | Time to do | Comment |
|---|---|---|
| Reverse proxy with a public certificate | An afternoon | Works for every browser; certificate must be valid and renewed automatically |
| Certificate from an internal CA | A day or more | Every device must trust the CA; unmanaged devices will fail |
| Self-signed certificate | Minutes | Does not work: HSTS removes the click-through |
| Wait for the lifetime to expire | Up to a year | Not realistic |
The self-signed route deserves a warning: it is the first thing people try, and under HSTS it fails exactly like no certificate. For names that are not reachable from the internet, a certificate can still be issued from a public authority using DNS validation, which proves control of the domain without exposing the server. Staff were back at work by mid-afternoon.
How the rollout should have gone
Start with a short lifetime. Five minutes is enough for you to see the header working and for any broken page to recover quickly. Then raise it to a day, a week, a month, and only then to a year, leaving time between steps to collect complaints. Leave includeSubDomains off at first. Turn it on only after listing every subdomain, internal ones included, and confirming each serves HTTPS with a valid certificate.
The list is harder than it sounds. DNS zone files collect old names for printers, test boxes, vendor portals and tools that predate the person doing the review. Look in the zone, in the certificate transparency logs for public names, and ask teams what they run. Anything on the list that cannot do HTTPS needs fixing first or needs to move to a different domain.
What would have caught it
- Introduce HSTS with a short lifetime first and lengthen it gradually.
- List every subdomain, including internal ones, before including them.
- Understand that you cannot easily undo HSTS in visitors' browsers.
- Test an internal name from a machine that has visited the main site, not only a clean one.
- Keep a certificate plan for internal tools before the policy change, not after.