Javascript and Security

Share this article

Dori Smith has a great entry on her Javascript Weblog about using Javascript to secure pages of her site. She argues that Javascript really isn’t the right tool for the job, and I completely agree with her. However, it is possible to yse Javascript to further improve the security of a server-side login system.

Unless you are using SSL, the chances are your site’s login system sends passwords in the clear. They may be embedded in a POST request but they are still fair game to sniffer programs such as Ettercap. While far from solving the problem entirely, you can reduce the impact of sniffing attacks by using Javascript to encrypt the user’s password before it is transmitted to your application. An evesdropper may be able to access your application using the data they have sniffed, but they won’t be able to access other applications that use the same password (most people use the same password all over the place).

But surely if the encryption is carried out by Javascript an attacker would be able to reverse engineer it and decrypt the password themselves? Not at all, thanks to the magic of one-way encryption algorithms – in particular, MD5.

MD5 is a one-way hashing algorithm. You give it an input, and it spits out an output. The trick is that there is no systematic way of retrieving the original input from the output aside from a brute-force attack. Javascript does not provide native support for MD5, but this free library provides an MD5 Javascript implementation specifically designed for preventing passwords from being transmitted in the clear.

Here’s a simplified explanation of how it works:

  • The web server serves up a form with a hidden field containing a random “challenge” string, and optionally a timestamp for when the form was served.
  • The user enters their password and submits the form.
  • Javascript glues their password on to the challenge and MD5 hashes them both. Only the hash is sent back to the server.
  • The server knows the user’s password and the challenge that was sent, so it hashes them and compares the result with the data sent by the user.

Naturally, when implementing such a thing it’s essential that the system functions even with Javascript disabled. You can do that by setting a variable in a hidden form field when the Javascript encryption method is used; the server can check if that field has been set and assume that the password was sent in the clear if it hasn’t.

If your web application stores encrypted passwords (as a well behaved application should) this technique can still be used – you just have to MD5 the password twice on the client side, once to get the encrypted version and then once with the encrypted version appended to the challenge to get the response which should be sent to the web server.

Example server side code for this technique can be found on this page of the Javascript MD5 site.

Simon WillisonSimon Willison
View Author
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week