Tuesday, November 30, 2010

Bookmarklets versus Man-In-The-Middle attacks

Let me start off by saying I don't consider myself a security expert. As a web systems developer I've had to become knowledgeable about security, e.g client-side password hashing, salted hashes, PKI, etc. But like many I've relied quite a bit on TLS/SSL to ensure that data moving between my systems and users is safe. In fact, if I were completely honest, I'd say it's been something of a crutch. If we point users to an https link, we feel like we've done what's necessary for security.

TLS/SSL has a pretty serious weakness, however, the Man-In-The-Middle attack. And MITM is a fairly trivial thing to do, thanks to the Address Resolution Protocol, which is used nearly everywhere for one physical device to find another on a network.

MITM is also trivial to do because smart and devious people like Moxie Marlinspike have exploited these weaknesses and created tools like sslstrip. With available tools and only a reasonable amount of knowledge, a "script kiddie" can implement MITM in around 2 minutes, and pretty easily trick you into giving away information. Think about that the next time you want to do your banking while sitting in a coffee shop.

The MITM attack is very difficult to circumvent programmatically, because (if you watched the video at the sslstrip link above) the attacker has the page first, and is able to manipulate it in subtle ways that are hard to detect. For instance, stripping out https links so when you login somewhere, you send your credentials for the attacker to view and capture.

Bookmarklets


Recently, I began to think about safe ways to do logins, assuming that a MITM attack was under way.

You could use public/private key encryption like RSA to encrypt the username and password with a public key before sending. However, if someone is in the middle, they could just as well manipulate the code to use a public key of their own, and then decrypt your credentials. It makes the attack harder, but not impossible.

So how can you ensure that the key (and code) you've obtained from the server hasn't been tampered with? This is where I thought of using bookmarklets. Bookmarklets are typically a bit of compressed JavaScript code that is stored in a link. When clicked, the JavaScript runs in the context of the current page. My idea was to do the following:

1. Create a login page that uses public key encryption to encrypt credentials before sending. Embed the public key in the page.

2. Use a hash function to generate a signature for the login page.

3. Embed the hash function along with the hash from Step 2 in a bookmarklet that you make available to users. Ask them to add it to their Bookmarks.

4. When users visit your login page, they would click the bookmarklet from their Bookmarks. It would process the current page and generate a hash, and compare it to the one in the bookmarklet. If the hashes didn't match, the user would be alerted.

Proof-of-concept


I ended up doing the following to test my theory. First, I created a bookmarklet for developers. When clicked, it traverses the page you're currently visiting and extracts text, elements, and attributes, generating a SHA1 hash from the combined values. It then outputs the JavaScript code along with the hash, which you can turn into a bookmarklet for your users.

To use it, drag the below link to your Bookmarks, visit your [login] page, and click the link. The code for the bookmarklet of your page will pop up in a new window. Use that code to make a bookmarklet to add to your site.

Generate SHA1 Validation Bookmarklet

Using the above validation-bookmarklet-generator-bookmarklet :), I've created the following example of a pretend login page that uses RSA to encrypt credentials before sending.

Here's the validation bookmarklet for my pretend login page:

CheckPage!

Drag it to your Bookmarks. Then, visit the login page below and click the CheckPage! bookmarklet to verify the login form hasn't been tampered with:

Fake login page with RSA encryption

(You can even click Login to see the encrypted info that will be sent to the server.)

As long as a user clicks the validation bookmarklet and heeds its warning (that is, doesn't continue regardless), an MITM attack could be mitigated, if not altogether prevented for this page.

Issues and miscellany


There are a few issues I see with this idea. There may (probably?) be more, but these are the ones that immediately come to mind.

1. A MITM attack may modify the page to remove the user hint to click the bookmarklet first, relying on users to be forgetful. The page isn't disabled in any way, so if it was compromised and the user goes ahead, their credentials may be captured.

2. An attacker may trick the user into 'updating' the bookmarklet to do nothing but alert them the page they are viewing is validated.

3. If every login page for every service created a bookmarklet, users wouldn't be able to manage them very well, and they'd become rather cumbersome.

For developers, it also becomes a hassle if the login page changes, even slightly. They will be dealing with a lot of users who suddenly can't validate the login page, and are possibly panicking.

I don't in any way think this is a panacea, but I do feel like the idea has some merit, and possibly there are other, better ways to implement something in a similar vein.

No comments:

Post a Comment