Archive for the ‘Security’ Category

HTTP Strict Transport Security (HSTS)

22 Jun

So a while back I was trying to get an A+ rating from for, 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 “” 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 * will always be accessed via HTTPS. So you could go to something like “” and your browser will immediately go to “” heck, you could even go to and it will immediately change to at least for the next 2 years. I use google apps so I had set “” to be a CNAME to which meant when you went to you pretty much got redirected to gmail. However, thanks to that statement above now resulted in the browser trying to go to which went to the IP of google’s servers which don’t support https. Essentially, I completely mucked up 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 * but maybe I can arrange for specific sites like 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 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 * 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, via HTTPS. Here’s a trick I learned:

Chrome, Opera: Cannot connect to the real <domain name>.

  1. In the address bar, type “chrome://net-internals/#hsts”.
  2. Type the domain name in the text field below “Delete domain”.
  3. Click the “Delete” button.
  4. Type the domain name in the text field below “Query domain”.
  5. Click the “Query” button.
  6. Your response should be “Not found”.

Very handy trick. However, for me, I tried to delete “” 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; then I saw this in the query “static_upgrade_mode: STRICT" which I then learned was because I had done that "permanent" option above. 

Thanks to Arran Schlosberg and StackzOfZtuff over at StackExchange for making it clear. I’ll paste what was written:

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 http:// (not 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 (  and it contained a long list of domains, a search revealed was among them.  That’s why I could not get Chrome to “forget” used HSTS no matter what I tried. Interesting. I guess I’m stuck using HTTPS whether I like it or not, hehe.

Deon's Playground

Placing whatever interests me and more