Setting up SSL/TLS on sites has gotten easier and cheaper, but it has always been the Achilles heel for a lot of web developers. One of the most common problems is not serving the login landing page over HTTPS.
Developers need to understand why it is important to serve the login landing page over HTTPS and how posting the user’s credentials over HTTPS is not enough.
Hacking an Insecure Login Form
To demonstrate the vulnerabilities that can be exploited on an insecure login landing page, I stood up a Microsoft Azure site SSLGotchas.com. On this site, the login landing page below is loaded insecurely over HTTP.
There hasn’t been any sensitive data exchange in this simple GET for the login form over HTTP. Therefore, as long as we post the users credentials over HTTPS we won’t be exposing the data in plan view/text of anyone listening (e.g. a packet sniffer https://www.wireshark.org or running a wireless adapter that supports promiscuous mode such as Alpa AWUS036NH).
Our form will post to a secure endpoint https://sslgotchas.com as seen below:
Finally, we can successfully, login after posting to the above secure route https://sslogotchas.com/account/login.
Why is this a problem? By loading a page over HTTP only to post to HTTPS, we lose one of the cornerstones of SSL/TLS, integrity. SSL/TLS provides integrity by ensuring that there has not been a compromise of the communication and the data in transit has not been tampered with. Therefore, it leaves the communication completely open to man-in-the-middle attacks.
The man-in-the-middle can come in a number of flavors; someone sitting in your favorite Starbucks with a Wifi Pineapple, or a malware infected computer which potentially has the ability to inject itself into the communication, again because it is unprotected over HTTP.
We can see that indeed the script was injected by Fiddler:
With the keylogger injected into the site, every 8 seconds it will capture any key presses and send the results to a completely independent site endpoint at http://stoleyourscribbles.azurewebsites.net/api/scribbles/stolen. Now, don’t get hung up on the 8 seconds, that’s only what I set it to for easier display of the entries on the backend which we’ll look at next. It could be milliseconds or more often if we like.
The end result is entries in Azure Table storage, which in our example represent the user’s credentials (view of Azure Storage Explorer 6):
I could have gotten a lot fancier and more human-consumable by rolling out the captured data to various sites and grouping it based on additional information. But the point I think is clear.
None of this would have been possible if the initial login landing page was loaded over HTTPS. In that case, the communications would be secure, and you would have preserved the integrity of the data in transit from someone manipulating the response.
Don’t Forget Server Validity
Another cornerstone of SSL/TLS is server validity. We’re making the assumption that the underlying endpoint where these credentials will be posted to is not only a legit server but the server that we expect. Part of the handshake setting up a secure communication between the browser and the server is validating the server. That hasn’t happened, and there is no verification before these credentials are sent off to the ether.
We can put additional validations in place (such as ASP.NET’s [RequireHTTPS] attribute) to ensure that resources that should be served over HTTPS can only be requested over HTTPS. Or through policies such as HTTP Strict Transport Security (HSTS) as examples of proactive measures. But, the bottom line is that even the login landing page must be served over HTTPS.
In the end, it is up to us developers to understand why serving even the login landing page over HTTPS is so important. Apparently, Mozilla agrees because, while I was writing this post, Firefox decided to explicitly warn in their developer build (starting in DevEdition 46) if you attempt to load a login page insecurely. When it comes to undermining the security of an application, it only takes finding the weakest link. In the case of circumventing the security provided by SSL, if an attacker can gain access before SSL is in place, then the damage is already done.