HSTS – The Missing Summary

HSTS – The Missing Summary

HSTS (HTTP Strict Transport Security) is a feature supported by all major browsers, and it’s a method for websites to declare that they should only be accessed securely over HTTPS and never over an unencrypted HTTP connection. If a site has an HSTS policy, browsers will refuse all insecure connections to that site AND prevent users from accepting insecure SSL certificates. This, however, can come with certain risks to availability if not implemented correctly, as you will read later…

HTTP Strict Transport Security was defined as a web security standard in 2012, in RFC 6797 as a way to prevent man-in-the-middle (MITM) attacks that use SSL Stripping. SSL stripping is a technique used by attackers to force an unencrypted HTTP connection in order to view, intercept, and/or modify potentially-sensitive information, which would ordinarily be sent over an encrypted HTTPS connection. A good example of this is session hijacking. To fool around with this yourself, look no further than ye olde ssltrip (official website here, GitHub here) – a tool that had its official debut at Black Hat about a decade ago.

Side Tangent: A somewhat-related, alternate solution to prevent MITM attacks is HPKP (HTTP Public Key Pinning), also known as certificate pinning, or SSL pinning, which causes headaches for developers and pentesters, and was actually deprecated in Google Chrome 67, yet it is still used (and often misused) by many web applications. It can work pretty nicely for mobile apps, but can be circumvented on jailbroken iOS devices (depending on version and jailbreak) using SSLKillswitch. Like HSTS, Certificate pinning can also come with some serious risks if not implemented correctly, which I may outline in a separate blog summary, but you can read more in-depth on the topic here.

How does normal HTTPS redirection work?

Well, when you type a name in the browser like google.com, and not specifically https://google.com, then the browser automatically assumes you are wanting to go to http://google.com. This works just fine and redirects you to the HTTPS version of the site, as long as the developers of the site have set up an HTTP-to-HTTPS redirect at the endpoint listening on port 80. It will also work if you are a security-conscious individual like myself, and happen to use the HTTPS Everywhere browser extension, which you can set to either automatically redirect to HTTPS versions of a site if it is available, or completely disallow all HTTP traffic to ONLY allow HTTPS connections from your browser — this is assuming you are using a desktop browser, because most mobile browsers support very limited (if any) extensions.

The Magic Response Header – the secret simple syrup of HSTS

A simple Nginx configuration would look something like this:

server {
    listen 443 ssl;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

When a HTTP-Strict-Transport-Security response header is sent from the webserver listening over HTTPS, it tells the browser, “from this moment on, for the next X number of seconds, do not EVER send me another plain HTTP request — if you’re going to talk to me, we speak our secrets over HTTPS ONLY.” And here is where things can get a bit tricky: the suggested default value for X number of seconds in a production implementation is 1 YEAR. That means that if you are developing a website and need to test it over HTTP after it has gotten an HSTS response header, you’re in for some discomfort. It’s not as simple as clearing your browser cache or “trashing ALL data since FOREVER” or whatnot.

See the warning in the featured image? I’m sure it looks familiar — almost like a normal untrusted certificate error…except you cannot click through to bypass it and access the site. You have to explicitly remove that site from the HSTS cache. In Google Chrome this would be located at chrome://net-internals/#hsts (you’ll have to copy/paste, because Chrome doesn’t allow links to it’s own internal URLs). If you are using other browsers, the process is similar, but if you’re using Windows, you’re pretty much just screwed — you can’t remove a site from the HSTS cache — you can only temporarily disable it, and if you’re facing this out-of-scope issue, just Google it.

But wait, there’s more! It gets more secure (or worse, depending on the situation)

There is also a feature of HTTP Strict Transport Security called HSTS Preloading, and it’s a powerful beast. It is a modified version of the above header and would look like this as a line in an Nginx config:

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

After you have that header implemented for all domains and subdomains, and the max-age value is at least 1 year, you need to head over to hstspreload.org and submit a form to have your domain added to the preload list, which applies to all major browsers. This list is no joke. It isn’t queried by browsers at all. It is HARDCODED into the BINARIES of each new browser release, which means NO HTTP FOR YOU…ever. There will never be an initial HTTP client that gets redirected to HTTPS on that first try. It will go straight to HTTPS every single time.

But wait again, there’s more again! It gets even more secure (and theoretically, more dangerous)…

Remember how one of the features of HSTS is to not allow connections with insecure SSL certificates? Let’s say there was an enormous breach and your CA got popped. If any Trusted Certificate Authority were to get compromised, operating systems and browsers would immediately release new patches and releases that removed them from their default trust stores, and if they didn’t take some as-of-yet unknown action to remedy this with the multitude of sites using certificates issued from those CAs, that would make your site COMPLETELY UNREACHABLE TO ALL USERS FOR AT LEAST 1 YEAR. What if there was an unforeseen scenario where browsers decided to stop trusting Let’s Encrypt, for instance, because what if their only method of authentication validation was TLS-SNI, which was deprecated due to a vulnerability to shared hosting environments? Browsers would immediately untrust/distrust(?) the CA, and your site would be dead in the water.

I know that’s a lot of theoretical “what-if’s”, and the risk level is not too terribly high for a Trusted Certificate Authority to get compromised — but I am just trying to make sure everyone understands the availability risks they are taking when implementing HSTS — especially going when taking the preload route.

Can you circumvent HTTP Strict Transport Security?

If you use HSTS preloading, according to Acunetix as of May 8, 2019, the only way an attacker could kick off that one-time HTTP-only request would be via an NTP attack scenario to make the browser think the max-age has expired in the HSTS directive (see “Bypassing HSTS” from Black Hat Europe in 2014).

HOWEVER, I have been using another tool pretty extensively in some of my research and attack scenarios called Modlishka Reverse Proxy, officially released on July 6, 2019. It is a surprisingly-simple tool written in Go, that according to its author, can be used for the following purposes:

  • Support ethical phishing penetration tests with a transparent and automated reverse proxy component that has a universal 2FA “bypass” support.
  • Automatically poison HTTP 301 browsers cache and permanently hijack non-TLS URLS.
  • Diagnose and hijack browser-based applications HTTP traffic from the “Client Domain Hooking” attack perspective.
  • Wrap legacy websites with TLS layer, confuse crawler bots and automated scanners, etc.

Here is an article by called “Hijacking browser TLS traffic through Client Domain Hooking” by Piotr Duszyński, written on the same date that Acunetix released their article “What Is HSTS and Why Should I Use It?” (May 8, 2019), but the article by Duszyński made big waves in the InfoSec community by describing how Client Domain Hooking attacks can bypass HTTP Strict Transport Security. At the time of this writing, Acunetix has not updated their post to reflect this particular attack vector.

Additionally, here is Piotr Duszyński’s follow-up article, which he released on May 20, 2019, called “Client Domain Hooking – Example Attack”, where he demonstrates the Proof of Concept. In his example attack, he is using the exact tool I referenced earlier, Modlishka Reverse Proxy, which wasn’t open-sourced on GitHub until July 6, 2019 — almost 2 months after the original debut of this PoC. It wasn’t until writing this blog post that I put 2 and 2 together and made the connection that security consultant, researcher, and developer, Piotr Duszyński, was actually drk1wi himself!

So, that’s the summary of what HSTS is, how it works, how it can break your shit, and how to completely bypass it. I hope you enjoyed.

Leave a Reply