If you are still wondering if your web server needs to be on HTTPS, I’d recommend you look at the answer yourself at https://doesmysiteneedhttps.com
To be clear, the issue I have with HTTPS, without the HSTS Header, is that, unless you’re security savvy and always checking for the green browser signal next to the HTTPS (truth be told, recent browser versions help a lot with that), you might miss on the fact that a man in the middle (MitM) attack is in progress by downgrading your usual HTTPS website to HTTP, or simply assume that the company/institution just decided to not implement HTTPS.
So, how easy is it to do a Man in the Middle (MitM) attack even with HTTPS and without HSTS set on the server? Very!
The following illustrates the lab setup. It’s a quite common setting in coffee shops, airports, or anywhere you decide to access the wireless “FREE-WIFI” network.
Having this setup, the attacker has to do some ARP poisoning, by telling the network gateway that the attacker is the victim, and telling the victim that the same attacker is the gateway.
This implies that, in this case, a linux box (kali) is routing packets through itself. This is done by executing echo “1” > /proc/sys/net/ipv4/ip_forward. The successful ARP poisoning can be easily verified by executing arp -a on the Windows victim host, in which you can tell that both IPs, .10 (hacker) and .138 (gateway) have the same MAC address.
At this point in time, you can just store all traffic by executing tcpdump -w dump.pcap and later extract any HTTP credentials (or other cleartext protocols) with tools like dsniff, wireshark, ettercap, and so on.
But what if it’s HTTPS? Now we are ready for the packet manipulation that will allow us to strip away the HTTPS and deliver simply HTTP to the victim. To do this smoothly, all we want is to intercept that typical “www.example.com” input into the browser, or stored (bookmarks) https://example.com, that will translate into an HTTP request, which would be then redirected to the HTTPS port. This is the usual scenario on HTTPS websites without the HSTS set, and to intercept the HTTP request, create a new HTTPS request to the original server, strip the content from it, and deliver it back to the victim, over HTTP, we’ll use sslstrip, by @moxie.
To do this we need to redirect all HTTP (tcp/80) traffic to sslstrip. This is done by executing iptables -t nat -A PREROUTING -p tcp –destination-port 80 -j REDIRECT –to-port 8080 and having sslstrip running while listening to that port.
To show you the behaviour of a well-known website that runs on HTTPS, without HSTS set, we’ll look into Skype (they do have HSTS but with a ridiculously low max-age of 10 minutes). The following screenshot shows the behaviour of a normal (not MitM) request.
But after having sslstrip running on our lab, and having the victim type “www.skype.com” into the browser, the page comes back… in HTTP instead.
After the victim inserts the credentials, these are stored by ssltrip by default on sslstrip.log file.
These are the username validations. The first “ninja” attempt failed, since the site validates your username before allowing you to insert the password, so I had to put in a real email address that exists on skype. And then, on the attacker machine you also have the passwords.
This is where the HSTS HTTP Header comes in. It protects the victim by letting the browser know that the page should not be requested in HTTP, but always on HTTPS, so the first request to an HTTP port will never be sent by the browser. Instead, an HTTPS request will be sent, and when an attacker tries to MitM it, they have to do so using a self-generated/bogus certificate. This can be done with sslstrip python sslstrip.py … -k ca.key -c ca.cert ssl 0.0.0.0 8443 after generating your certificates with openssl, or more easily with tools like Cain&Abel.
Now we have two scenarios. The first one is a website that does not use HSTS HTTP header, and in the second scenario it’s used.
First scenario (without HSTS):
Second scenario (with HSTS):
Can you tell the crucial difference? On the second (safe) one – facebook.com – the browser does not allow for the victim to bypass the insecure connection warning. This is key! As a system administrator, if you know your website is only provided in HTTPS, bypassing the insecure connection warning should never be an option.
And those are the two reasons why you should have the HSTS header set on your web server. It forces the first browser’s request to get out using HTTPS, and it does not allow for the insecure connection warning bypass.
Not a silver bullet against HTTPS MitM attacks
Scenario #1 – first time access to the URL:
Even if a web server has the header configured, the victim will still be vulnerable on the first ever access to it. This is why the preload directive exists. It allows for browsers to have a pre-defined list of hostname that should only be accessed through HTTPS. This way even if it’s your first ever facebook login, for example, it will still send it through HTTPS even if you type “https://facebook.com“.
Scenario #2 – governments or powerful entities doing MitM:
In this scenario, one typically assumes that such an entity is capable of generating certificates that will be considered valid by browsers. Such attacks have occurred and will continue to, on well known totalitarian regimes.
Just so we’re clear, this was never something that HSTS was supposed to solve. That’s an issue for HPKP (which Scott Helme argue convincingly that is dead) and Certificate Authority Authorization (CAA) DNS records.
Major security testing tools report the lack of HSTS as a Low or Medium issue
That’s because tools can’t tell the importance of the data you have on your web server, so they would rather not cry wolf and have you ignore other High risk issues. But giving hackers the possibility to change any of your website’s data, from altering images to reputation-damaging ones, to changing bank details from donation sites, or to change the company’s contact number and later perform social engineering attacks, there are no good reasons to keep providing access to your website using HTTP or poorly configured HTTPS (without HSTS).
That’s also why you should not rely simply on tools. There are many good reasons for having an experienced penetration tester looking at your servers, and this is one of them… and also being able to detect more complex vulnerabilities and bypasses, and not stop checking for a SQL injection because ‘ or 1=1 # did not work.