SSL Stripping is an attack originally discovered by Moxie Marlinspike (@moxie) and released at BlackHat DC 2009 along with a tool called SSLStrip. SSL Stripping is an attack that takes advantage of the fact that server-side redirects are used to pass clients from HTTP versions of a page to the HTTPS, SSL encrypted, version. SSL Stripping tools, such as SSLStrip, listen for requests from clients which receive a response intending to forward the client to the HTTPS version of the page. SSL Stripping tools hijack this response, make the SSL encrypted HTTPS connection to the server, convert all instances of “https” to “http” within the legitimate content, and pass the modified content to the unsuspecting client over unencrypted HTTP. The attacker can then view all of the traffic between the client and the server in cleartext. I know what you’re thinking, “Why not just conduct an HTTPS man-in-the-middle?” The benefit of SSL Stripping over HTTPS mitm is that HTTPS mitm requires that the target client accept an invalid or untrusted SSL certificate in order to complete the attack, an obvious clue to the target that something is amiss. SSL Stripping provides very few visual clues that the target is being compromised.
Now, on to the reason for this article.
I was recently confronted with a challenge find a way to defend against an SSL Stripping attack. Initially, I gave the easy answer, “Train your users to always manually type in “https” before every site they visit which uses SSL encryption.” How realistic is that? Not very. So the solution had to be automated in such a way that it was seamless to the user and controlled by the administrator or application developer. As we said above, SSL Stripping attacks target the client’s trust of the response from the server. So in order to prevent SSL Stripping, the client must be responsible for ensuring that SSL is used where needed. Sounds dangerous right? Putting any level of control in the hands of the client. Well, in this case, we have no choice. The client HAS to be the decision maker here, as SSL Stripping tools specifically take advantage of this deficiency in the client.
The solution I came up with ended up being rather simple. Developers can add several lines of JavaScript code to the client-side portion of their application which forces the client to enforce SSL encrypted HTTP (HTTPS) without the direction of the server. Now before you start flaming this article, let me finish. It must be understood that while this will work, a mitm still has control over all cleartext responses from the server to the client. Therefore, if the mitm is aware of the anti-SSL Stripping mechanism, they can customize their SSL Stripping tool to also strip the anti-SSL Stripping code out of the response, rendering the client defenseless.
Moving forward, the following JavaScript code will force the client-side of an application to connect to the HTTPS version of each page on which the code is executed. Placing this code on the top of a page will defend against SSL Stripping attacks on that page.
var proto = String.fromCharCode(104,116,116,112,115,58);
if (window.location.protocol != proto) {
window.location.href = proto + window.location.href.substring(window.location.protocol.length);
}
Let’s walk through the code.
Line 1 creates a variable called “proto” which has a string value of “https”. The reason we create the string this way is to avoid where SSL Stripping tools search and replace all instances of “https” with “http”. SSL Stripping tools could add this to the search and replace, but think of how many different ways we can create and obfuscate JavaScript code to create a string equal to “https”. Actually, it’s limitless. Consider the following JavaScript:
var proto = String.fromCharCode(105-1,114+2,118-2,110+2,118-3,55+3)
This creates the string “https”. As long as we’re dealing with math, we have unlimited possibilities. Line 2 checks to see whether the protocol of the current location of the DOM is “https”. If it is not, then line 3 redirects the client to the “https” version of the page. Since the decision is being made on the client side, SSL Stripping tools do not have the opportunity to hijack the redirect from the server, and SSL Stripping is averted.
UPDATE:
I quickly received a lot of responses to this article concerning HSTS (HTTP Strict Transport Security). HSTS does something very similar to what I do in this article, but it standardizes it so that browser developers will have the security measure built in. HSTS is OPT-IN and is activated by the use of a “Strict-Transport-Security” (STS) header from the server. The STS header must be transmitted from the server to the client via HTTPS, so the issue still remains that the connection, if initially made over HTTP, can be hijacked and “SSL stripped”. Using JS to enforce HTTPS for that initial requests adds an extra layer of security to ensure that the client is able to make that initial request for the server over HTTPS and receive the STS header to protect future connections.
UPDATE:
For a spirited debate on the validity of this technique, see http://www.reddit.com/r/netsec/comments/149y3s/defending_against_ssl_stripping_attacks/
Join me for SEC542: Web App Penetration Testing and Ethical Hacking at SANS Monterey 2013!
Monterey, CA | Fri Mar 22 – Wed Mar 27, 2013