Learn how man-in-the-middle (MITM) attacks can put your website users in danger and how to prevent it. The original post can be read here
What are MITM attacks?
In a MITM attack, someone on the network intercepts the network communications between a user and your website.
How are MITM attacks made?
There are multiple ways to hijack someone's network connection, but two standard methods are ARP poisoning and evil access points.
ARP poisoning
Hosts on a network talk to the world outside of the local area network (LAN) through a gateway. The gateway is configured on the client, either manually or through the DHCP protocol.
Communication within a LAN, however, is facilitated through MAC addresses, not IP addresses. For this reason, we need a protocol to map IP addresses to MAC addresses to communicate with hosts on the network by their IP address. And this protocol is aptly named address resolution protocol or ARP for short.
Here is how the ARP poisoning attack works.
The attacker sends an unsolicited ARP reply to the target network device (e.g., the website user's phone), claiming that the attacker's device is the gateway. And the way network protocols are implemented, the phone will believe the attacker and start sending its traffic through the attacker's device.
Evil access points
The second typical attack works by the attacker setting up a WiFi access point that mimics a real access point nearby.
When users unwittingly connect to the malicious access point, their network traffic is sent to the attacker, who then forwards it to the Internet.
sslstrip
Once the connection has been intercepted, the attacker can use a tool such as sslstrip to disable all HTTPS redirects and change https://
links to unencrypted http://
.
It shouldn't matter
The key takeaway here is that developers cannot base an application's security on the assumption that no-one can intercept the connection between the user and the webserver.
Instead, we have to use encryption to make sure it doesn't matter whether the connection is hijacked or not.
Does HTTPS prevent MITM attacks?
Unfortunately, HTTPS alone is not enough to prevent MITM attacks against your users. Let me show you what I mean. The following is generally what happens when a browser connects to a website:
- The user types in www.example.com
- The user's browser sends an unencrypted HTTP request to http://www.example.com/
- The webserver returns a redirect to https://www.example.com
- The user's browser sends an encrypted HTTPS request to https://www.example.com/.
- The webserver returns with the login page.
- The user enters their username and password, which the browser safely sends to the webserver across a secure TLS connection.
But what if there is an attacker on the network?
- The user types in www.example.com
- The user's browser sends an unencrypted HTTP request to http://www.example.com/
- The attacker intercepts this unencrypted request and returns the login page from the real server. Crucially, the connection is still unencrypted.
- The user gives their username and password straight to the attacker over the unencrypted connection.
See the problem? The web server never got a chance to redirect the user to HTTPS because the attacker had already taken over the connection.
How to prevent MITM attacks?
There are three key requirements for protecting your web application from MITM attacks:
- Use HTTPS.
- Use preloaded HSTS.
- Harden your SSL/TLS ciphers.
Use HTTPS
The first defence is simple, and hopefully you are already doing this. Get a free certificate from Let's Encrypt and use HTTPS for all your content.
Use preloaded HSTS
HSTS (HTTP Strict Transport Security) is an opt-in browser security feature that prevents browsers from making any unencrypted connections to a domain.
The following is how the network flow might work with HSTS enabled:
- The user types in www.example.com
- The website uses HSTS, so the user's browser right away sends an encrypted HTTPS request to https://www.example.com/. The attacker doesn't get a chance.
- The webserver returns with the login page.
- The user enters their username and password, which the browser safely sends across a secure TLS connection.
See how HSTS prevented the attack? The browser never sent the first unencrypted HTTP request, and the attacker had nothing meaningful to intercept.
You can enable the protection for your website with the Strict-Transport-Security
header. Make sure to include subdomains and enable HSTS preloading. You can read more about the options and what preloading means here: HTTP Strict Transport Security (HSTS).
Harden your TLS ciphers
You can use preloaded HSTS to force connections to your website to be encrypted. But what if someone breaks that encryption? You have to be careful when configuring the TLS settings on your server.
Implement forward secrecy
One of the most important things is to use a key exchange algorithm like Diffie-Hellman that doesn't involve transmitting the symmetric key over the network. Otherwise, such as when using RSA for key exchange, if someone in the future gets access to the private key (remember heartbleed?), the attacker can decrypt all of the past encrypted connections.
This property is called forward secrecy or perfect forward secrecy. Make sure you have it enabled.
Use authenticated encryption
Use cipher suites that verify the authenticity of a message before trying to decrypt it. This way is much less prone to all sorts of attacks like padding oracles. AES-GCM and ChaCha20-Poly1305 are such good ciphers.
Disable legacy protocols
It's important not to support legacy protocols because an attacker on the network can downgrade the connection to the worst settings supported by both the client and the server.
- Only support TLS 1.2 and up.
- Only support SHA and SHA2 (SHA256, SHA384, etc.) for the MAC (Message Authentication Code).
- Only support AES-GCM from block ciphers and ChaCha20-Poly1305 from stream ciphers.
You can check the browser support for TLS 1.2 here.
Generating a secure configuration
Visit Mozilla's SSL Config to generate a secure configuration for your webserver.
Conclusion
The users of any web application can be targeted with MITM attacks even if the website uses HTTPS. Luckily developers can take some measures to protect an application from these attacks. These are:
- Use HTTPS.
- Use HSTS and preload it.
- Configure your server's TLS settings appropriately.
Get the web security checklist spreadsheet!
☝️ Subscribe to AppSec Monkey's email list, get our best content delivered straight to your inbox, and get our 2021 Web Application Security Checklist Spreadsheet for FREE as a welcome gift!
Don't stop here
If you like this article, check out the other application security guides we have on AppSec Monkey as well.
Thanks for reading.
Top comments (8)
As always another great and informative piece! ❤ 🦄
What happens if I only support TLS 1.2 - what happens to IE9 and 10 users then, do they simply get no access to the site (I have HSTS preload etc.)
Thanks, glad to hear!
What would happen is that they wouldn’t be able to open your website at all. But do you really care? Even Microsoft doesn’t support IE10 anymore: docs.microsoft.com/en-us/lifecycle...
I deal with accessibility, around 3.6% of people who use a screen reader are stuck on IE10 and below due to hardware and software constraints.
So I still support back to IE9 with full or equivalent functionality (depending on the site).
That sucks! I hope things will improve for those 3.6% of people asap :)
Haha - the webaim screenreader survey should hopefully come out and show it dropped to less than 1% soon, then I too can enjoy the world where I only have to worry about IE11 (which to be fair has 99% of the features you would want to use on a website)!
I saw this from the dev.to main page.
As it is about application security, it interests me. ;-)
And I wasn't disapointed. Your content is brilliant.
I am going to read more of it.
Thank you for your work.
Ok
But how does the preloaded HSTS happen BTW?.
Is it that as a developer they should configure in JavaScript.
Or does it happen through a end user browser?
Hey!
HSTS is facilitated via the Strict-Transport-Security HTTP response header, and preloading is done at hstspreload.org. You can read more here: appsecmonkey.com/blog/hsts