Secure authentication with JavaScript

When creating a user authentication system, security is very important. Guides to building authentication systems for a web application often discuss storing user passwords as hashes of the real password in the database. This prevents the password from being stored in plain text, and as such the real passwords are protected from anyone who might gain access to the database. When a user registers a new account, the password is hashed by the application and then stored in the database. Whenever they subsequently log in, the password they use to log in is hashed and compared to the hash stored in the database. Since hashes are unique, if the two hashes match, the user has entered the correct password and is successfully authenticated.

What is very often left out is that when using this method, the user's password is still being sent unencrypted across the Internet in order to reach the server, both when they register and every time they log in. Because the password hashing occurs only on the server side, the password is protected from a compromised database, but it is not protected from man in the middle attacks, in which a hacker snooping for packets sent across the Internet intercepts the data as it goes by.

In order to protect against man in the middle attacks of this nature, the password needs to be encrypted in some way before being transmitted to the server. The easiest way to do this is to encrypt the entire process using SSL. This encrypts all data as it is transmitted and the user knows this because they can see the page is secured with SSL from their browser. Since SSL requires a certificate that costs money, this may not be an option for some developers, especially those on a budget or those using shared web hosting.

Fortunately, there is an alternative that costs nothing at all and will work on any server setup. All that needs to be done is to use JavaScript to hash the password on the client side before the data is transmitted. This can be achieved by including any JavaScript hashing library and using JavaScript to run the password through this function using an onSubmit event handler. This simple procedure safeguards against an often overlooked security hole in authentication systems. Take some time to add it to yours – your users will thank you!

Comments

sadinpants sadinpants commented
July 01, 2009

This doesn't really guard against anything. There is a reason SSL is used (to protect against eves dropping, amongst other things). While your method does keep the user's password "secret" it doesn't prevent somebody from authenticating as them. Take into account your user sitting at a cafe using free wifi and wanting to log into one of the websites you designed them (and bill as secure). There is nothing preventing the attacker from sniffing the airwaves and finding the hash (which we'll call a password because that's what it is). Now while the attacker doesn't know the [original] password, that doesn't matter because your website accepts the hash as the password [authentication token]. So 5 lines of perl, or perhaps even quicker use of paros proxy an attacker has authenticated as the user by posting the hash and the user's name to the website. Congrats on re-discovering a very old bad practice.

I hope your clients still decide to use SSL, and not trust you when it comes to security. Although you have some nice sites in your portfolio.

Jimmy Cuadra Jimmy Cuadra commented
July 01, 2009

sadinpants,

You are right in that what I describe here doesn't prevent against relay attacks. I see how this article misleadingly suggests that only hashing the password on the client side makes the authentication secure. But you are correct, this doesn't prevent a relay attack (perhaps part of the confusion is that I refer to password snooping as a "man in the middle attack" here).

To prevent a relay attack, there must be some sort of additional safeguard such as a challenge/response or time-limited authentication key. Given the response to this post I will likely write another that goes into detail about that.

Thanks for your feedback!

Comments are closed

Comments are automatically closed 2 weeks after publication. If you still have something to say about the article, feel free to contact me.