.Net Dojo: Forgot Your Password Workflow
As an experienced web developer, I have seen all kinds of crazy login workflows. The security question workflow, however, is the absolute dumbest workflow ever. Not only are most questions geared at public domain information, but how many people are actually going to remember what they typed in for their answer? Also, depending on how good (or bad) the programmers are, if the answer is case senstive, or miss-spelled, you are hosed. I can’t stand sites who use this workflow when there are much better, and more secure ways to allow users to regain control of their account. To learn more about why this type of authentication is bad, read Wish it was Two-Factor by Alex Papadimoulis. He discusses how the secret question does not fullfill two factor authentication by any means.
Case in point - Facebook. In January 2007 I changed my e-mail address used by facebook. I was losing access to the e-mail it was registered on. Well, Apparently I didn’t verify the e-mail address which sent my account into a sort of “limbo.” I e-mailed facebook and asked to have my account password reset because I couldn’t get in, and it was not showing that my original e-mail even had an account. While facebook does allow you to enter your e-mail to reset your password, when you deal with their customer service, they ask your secret question. I could not remember the answer to my question, and had my request denied….twice. I came to find out, through them leaking the actual e-mail my account was assigned to, that it had reverted back to my original e-mail - my college e-mail account, which I did not have access to. After my second denial I simply wrote them back “I regained access to my account. Thank you for being absolutely useless.” The secret question does no good when you can’t remember the arbitrary answer you entered. The only reason I even got back into my account was because Facebook broke any guidelines they have around privacy and told me the e-mail address registered to my account.
Banks who use the security question workflow should not be trusted. The workflow is not secure, expecially when they use questions like “what is your mother’s maiden name” or “what city were you born in.” This is public domain information, retrievable by anyone who has the knowhow to steal your identity. For this reason, if your bank uses this type of false security, I recommend you complain and refuse to use their website (or find another bank). They are required by law to use two-factor authentication and a secret question is NOT two-factor authentication.
The best workflow I have seen thus far is a system where the user is given 3 attempts to login. If the 3 attempts fail, or they know they don’t know the password, they may enter their e-mail address. But what if the user doesn’t remember their e-mail address? Well, that poses a problem that I will leave to you to solve. Once the e-mail address is successfully entered, the user would recieve an e-mail containing a url with an encrypted querystring. This Querystring contains the user Id, e-mail address, a “secret word,” and a date-time stamp. This link “expires” after 48 hours. You could go more secure by having a system that keeps track of pasword reset requests and allows this link to work only once, but I typically think a url using html encoded Rijndael (AES) encryption is good enough.
Here is how I build the link that I typically use for a “forgot your password” workflow.
string email= textBoxEmail.Text.Trim();
//Get the user ID using the entered e-mail
int userId = GetUserIdFromEmail(email);
//impossible to guess string
string verificationKey = "1F0r6otmYP4$Sw0rD";
//piece the items together
string compsiteKey = userId.ToString() + "|" + DateTime.Now.ToString() + "|" + verificationKey + "|" + email;
string querystring = Olympus.Encryption.EncryptQueryString(compsiteKey);
Let’s break this down into steps.
1. Get the e-mail from the text box. A step not included is to make sure the e-mail belongs to a valid account.
2. Get the database’s ID number of the account stored in the database. Typically I use an identity column on this table. You can use whatever. I reccomend using the e-mail and database ID together to make sure the data has not been tampered with.
3. Get an verification key. Make this something impossible to guess. Typically I use the web.config to set the key per site.
4. Add the 3 values plus a time stamp. This is important to make sure the link hasn’t “expired”
5. Encrypt the data. Take a look at my post on how to encrypt with .Net to see why I’m encrypting the querystring using a special method.
The url should point to another page that looks for the querystring value. If it’s empty, don’t allow a reset. If it won’t decrypt, don’t allow a reset. If it doesn’t have 4 pieces of data after splitting on the “|”, don’t allow a reset. If the Time stamp is outside the allowed buffer, don’t allow a reset. If the verification key doesn’t match exactly, don’t allow a reset. If the database Id and e-mail don’t belong to the same account, don’t allow a reset (be careful of this in systems where a unique e-mail is not enforced). If it passes, allow the user to reset their password. As a courtesy, log them in to your site after resetting the password.
My method is on the bottom of the more secure way to do this workflow, but avoid, at all costs, the “Security Question” workflow. Your users will thank you.
No comments yet.
Leave a comment
-
Archives
- June 2008 (3)
- May 2008 (1)
- March 2008 (1)
- February 2008 (6)
- January 2008 (6)
- November 2007 (18)
-
Categories
-
RSS
Entries RSS
Comments RSS