So a while back I was trying to get an A+ rating from ssllabs.com for glitchsys.com, because, why not? I followed a guide on hardening NGINX for SSL and I went from a C to an A+. It was awesome. However one of the things they had me add to my nginx.conf file was:
# Enable HTTP Strict Transport Security (HSTS) add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
Now I was vaguely aware of what this did, but not fully. Let me break this down for you. It will add that HTTP header to all HTTP requests.
- So, 63072000 is in seconds, that large number translates to 730 days, or 2 years. So you’re telling the browser that for the next 2 years, always use https when accessing the domain. Now if somebody typed in “www.glitchsys.com” your browser may quickly make a HTTP connection, at least the first time, see that header and immediately reconnect via HTTPS and it will continue to do so for the next 2 years.
- Also “includeSubdomains” means that *.glitchsys.com will always be accessed via HTTPS. So you could go to something like “blahblah.glitchsys.com” and your browser will immediately go to “https://blahblah.glitchsys.com” heck, you could even go to http://blahblah.glitchsys.com/ and it will immediately change to https://blahblah.glitchsys.com/ at least for the next 2 years. I use google apps so I had set “gmail.glitchsys.com” to be a CNAME to ghs.googlehosted.com which meant when you went to http://gmail.glitchsys.com/ you pretty much got redirected to gmail. However, thanks to that statement above now http://gmail.glitchsys.com/ resulted in the browser trying to go to https://gmail.glitchsys.com/ which went to the IP of google’s servers which don’t support https. Essentially, I completely mucked up gmail.glitchsys.com because that subdomain had to be http and not https. Oops.
- I’m actually going to see if there is a way to “undo” HSTS for a specific sub domain. I’d like to have HSTS enabled for *.glitchsys.com but maybe I can arrange for specific sites like gmail.glitchsys.com to not use HSTS. I doubt I can do it though because…
- And lastly, that “preload” action at the end turned out to be a lot more interesting than I thought. It turns out there is a chance somebody could theoretically intercept traffic to http://www.glitchsys.com/ and try to get rid of that Strict-Transport-Security (HSTS) line in the header, so to compensate you can add preload line which somehow gets your domain submitted to Google where it gets included in this large file and all future versions of Chrome will have this file hardcoded into it and will always go to your domain via HTTPS. Let me repeat that, Chrome is now hardcoded to go to my site *.glitchsys.com via HTTPS and there’s nothing I can easily do to stop it. You actually have to remove permanent, set max-age to 0 seconds and submit a request to Google to have your domain removed and then in future versions of Chrome your domain won’t be included, which means it’d only affect people who download the new version of Chrome. A slow change over the course of many months. So yeah, be careful with “permanent”.
Ok so Chrome does not store these settings, like if your domain must be HTTPS, in cache. You can clear your browsers Cache and it will still remember to go to your domain, like glitchsys.com, via HTTPS. Here’s a trick I learned:
Chrome, Opera: Cannot connect to the real <domain name>.
- In the address bar, type “chrome://net-internals/#hsts”.
- Type the domain name in the text field below “Delete domain”.
- Click the “Delete” button.
- Type the domain name in the text field below “Query domain”.
- Click the “Query” button.
- Your response should be “Not found”.
Very handy trick. However, for me, I tried to delete “glitchsys.com” and then I immediately did a query and it was still there! I tried over and over again, cleared my cache, tried again, no matter what I did I could not remove glitchsys.com; then I saw this in the query “static_upgrade_mode: STRICT" which I then learned was because I had done that "permanent" option above.
If either of the
static_upgrade_mode: or the
dynamic_upgrade_mode: lines are set to
STRICT then HSTS is enabled.
Dynamic means that the browser has been instructed to enable HSTS by an HTTP response header (served over TLS) similar to the following:
Strict-Transport-Security: max-age=157680000; includeSubDomains;
This is vulnerable to an attack whereby the very first time the browser requests the domain with
https://) an adversary intercepts the communication.
In order to overcome this weakness we have the
static mode which allows for hard-coding HSTS records directly into the browser’s source. The header is changed to indicate the administrator’s intention:
Strict-Transport-Security: max-age=157680000; includeSubDomains; preload
Note the inclusion of
preload at the end. The domain is then submitted for manual review. If approved then it is added to the Chromium list which is also included in the Firefox, Safari, and IE 11+Edge lists.
So I went over to the Chromium list (https://chromium.googlesource.com/chromium/src/net/+/master/http/transport_security_state_static.json) and it contained a long list of domains, a search revealed glitchsys.com was among them. That’s why I could not get Chrome to “forget” glitchsys.com used HSTS no matter what I tried. Interesting. I guess I’m stuck using HTTPS whether I like it or not, hehe.