Good practice to reset password

I’m gonna implement a ‘reset password’ feature in a WE app and just want your expertise!
I’m thinking about this approach:

The user enters their accounts username and the associated a-mail address that are validated. (Also thinking about a captcha here to make it harder for automated scripts here…)
A unique singel-use key is generated and inserted into the database.
An expiration timestamp is also inserted to make the key valid for something like 45 min.
An e-mail is sent to the users registered e-mail address that contains a link with the single-use key as a parameter.
When the user clicks on the link she’s taken to the app that reads the parameter.
The user is asked to enter her username and e-mail address again.
If the username, e-mail and single-use key is validated against each other, the user is told to enter a new password.
Invalidates the key in the database so it can only be used once.

Any thought on this approach? Pros, cons? :slight_smile:

I would avoid the need of the username for the reset, people sometimes just forget that. I would keep it simple. The reset form asks for the email to be reseted, and internally generates a reset key, only valid for that email, and send a link like https://www.myapp.com/resetpassword.cgi?e=my@email.com&k=384a99d23f773 to that email.
The user, the person who owns that email, receives the reset password link, if he ignores it, nothing changes, but if he clicks the link, we do know the he is the owner of that email, and he is presented to a form asking just the new password (twice for checking). Once done, or some other instance on the planet clicks on “reset password”, the last reset key will be invalidated or changed to a new one, making that link invalid.

The garbage was inserted by the forum. :slight_smile:

https://www.myapp.com/resetpassword.cgi?e=my@email.com&k=384a99d23f773

If you need extra security, you could implement security questions on the user record, and ask the question and receive the answer in addiction to the new password, for a second check.

Ex. Hypothetical user record: {id:“111”, name:“Rick”, email:"my@email.com", question “What’s my favorite coffee blend?”, answer:“my special blend”, resetcode: “384a99d23f773”}

Warning: People forget the answers too, or how they wrote them.

Heck I forget how I wrote my security answers also :slight_smile: :slight_smile:

Simple is best due to that, you just need a valid email. But when you really need protection, you must implement extra security and even have a support team to personally recognize the user and unlock their account. Imagine, for example, the possibility of someone losing access to that email account by some reason (or saying so). Or you implement some kind of change email routine, after some more security check, or it needs manual intervention by the support.

I don’t know if asking for both the username AND e-mail would add some security over only the e-mail?
If the users can’t remember the username they most likely wont remember the answer to a security question, no.

Yeah, people really don’t want security questions(I know I don’t) as most of them don’t answer with the “real” answer just to get rid of them :wink:
“What was your first pets name?”
-“don’t remember” Good luck remembering that answer.

Thanks on the tip on having two parameters in the link, E-mail AND key to validate against each other! :slight_smile:

Would encrypting the email/key in the link to add security or would I just be overcomplicating it?

People really don’t like that. For the sake of sending a reset email, it’s an extra almost unnecessary step that will increase the number of calls to your support because people don’t forget emails but forget that weird username like RICK238 (RICK was already taken). But if go this way, be prepared to “recover username” + “reset password” routines.

People HATE (myself included) pre-made questions like “What’s the name of your first pet?” (“Hey mom! Did I have any pet?”). But don’t care much about a made by themselves like “What is written behind the special bathroom mirror?”. But even this adds the “Extra step, people not concerned about security, hate”. If you consider this step, try to check the quality of the question and the answer (like ignoring “the”, “of”, etc and see what’s left).

You can even have 2 equal reset keys on the database this way with no problems. Your server logs will have this visual tip to help you tracking attacks in case of someone trying to break into the system. Some people could think that having the email shown could weaken the security, but not, if someone intercepted the reset email, they already know the email, so it does not affect this security level.

Overcomplicating. An attacker already have the email data. It’s on the reset line just to help humans reading logs.

Don’t use security questions, they’ll only make your system weaker.

The problem with questions is they’re almost always bits of information that a 3rd party could know. They rely on obfuscation, which isn’t really security.

For example, if my questions are “what was the name of your elementary school” and “what is your mother’s maiden name”, just about anybody in my family would know those answers. If I were to go through a messy divorce, my ex might use that against me. Or maybe I get into a fight with my brother. Or maybe an attacker can find those details through some clever searching. The point is, they introduce an additional attack vector based on information that does not prove identity.

Your original plan is solid. If you want to add additional security, look into two-factor authentication. Don’t bother with captchas and security questions.

Thank you for your input guys! Much apriciated! I’ll need some time to get it working. I’ll return with how I did it for future reference :slight_smile:

Okay, I’m now almost done with this feature. It’s just some fancy UI stuff left so I thought I’d share how I did it.
1. The user enters her registered e-mail.
2. A unique generated key is inserted into the DB along with a timestamp to make the key valid for 30 minutes.
3. An e-mail containing some info and a “Reset link” is sent to the e-mail provided. This link has two parameters.
The username and the key for the user assigned to the e-mail given.
4. When the user clicks on the “Reset link” she’s taken to the app again and it reads the parameters and does some validation against the database. If the validation succeeds, a dialog appears that asks for a new password to be entered twice.
5. The new password is saved into the database.
6. Everyone is happy!

Yes, there are quite many error checks going on! :wink:

(Still thinking about a captcha or something at #1…if it adds some level of security.)

[quote=64213:@Albin Kiland]5. The new password is saved into the database.
[/quote]

By that, you mean a properly hashed version of the password, not the password itself, right?

Right on Kem. Of course I do :wink:
I actually use the authentication system suggested and described by Thom.
Took a while for me to implement but it works like a charm! :slight_smile:
http://thezaz.com/blog/2013/12/storing_passwords_securely_wit.html

That reminds me. Thank you Thom for that great blog post :slight_smile:

Note to self for the last time: Stop overusing smileys…

You’re welcome.

[quote=64292:@Albin Kiland]I actually use the authentication system suggested and described by Thom.
Took a while for me to implement but it works like a charm! :slight_smile:
[/quote]

Cool. I’ll actually be doing a session on this at XDC.