james mckay dot net
because there are few things that are less logical than business logic

Easy login recovery without compromising security

I’ve noticed recently that some websites have a very elegant solution to the problem of login recovery. If you forget your password, rather than sending you an e-mail with either your existing password or a new one, they send you a link that you can click on, which takes you straight to a page that logs you in automatically and allows you to choose a new password.

This works particularly well because it fixes the problems of both the “password reset” and “password reminder” approaches. Password reminders are bad because they require you to store the users’ passwords in plain text in the database, but password resets are also bad because they are completely user-unfriendly.

Not long ago we deployed a website for a client that used the ASP.NET membership provider for authentication and generating passwords. Unfortunately, we had to change it, because the ASP.NET membership provider generates seriously ugly passwords that look like “aFi$#3-Il1=+2x{zZ14^” or something, prompting at least one user to send in an e-mail that said this:

I tried starting again from scratch and this time I was assigned a 21-character (!) password – the sort of thing you would expect to use if you were trying to get into Fort Knox … I find your site definitely “user-unfriendly”. What can I do?

This is why some teams settle for password reminders, even though they may be aware of the security risks. It’s also one thing that I dislike about the ASP.NET membership provider.

The login link approach gives you the best of both worlds and offers additional advantages on top of each. It bypasses both the login page and the process of navigating to the page that lets you change your password (which many users find confusing), making it much more user friendly than either. Certainly you won’t be asking your users to faff about copying and pasting “aFi$#3-Il1=+2x{zZ14^” from their e-mail client to the login page. Furthermore, because your password is not reset until you actually change it, your old one will continue to work if you manage to dig it out in the meantime. And from a security point of view, you can still store passwords as a salted hash in the database.

2 comments:

  • # Reply from chad at 00:00 on 22 Jul 2008

    Hi James,

    Thanks for the post. I was curious if you found a way to implement a link-based password reset function in a MembershipProvider implementation. As far as I can tell, one of the existing methods would have to be hijacked in order to do it. Is there a more elegant way?

    Thanks,
    Chad

  • # Reply from James at 19:40 on 22 Jul 2008

    It’s a bit awkward because the ASP.NET membership provider and login controls aren’t really designed with this kind of scenario in mind, so you will need to do a bit of coding to achieve it rather than the usual drag and drop. In particular:

    1. Changing a password with the ASP.NET membership provider requires both the old password and the new password. However, you can get round this by calling MembershipProvider.ResetPassword and passing the result to MembershipProvider.ChangePassword.

    2. You’ll need to roll your own equivalent to the PasswordRecovery control as it isn’t designed with this in mind. It either sends out the user’s old password or else it resets it to a new one and sends that instead. Also, if you want to send out links that expire after, say, a couple of hours or so, you will need to add an extra table to the database to contain them.

Comments are closed.