Ask HN: Strategy for password reset email vs URL to reset pwd
What do you guys think is a better and safer way to handle forgot password? Many sites out there reset and create a temporary password and send it in email in plain text.
Others normally ask you to provide email and send a link via which you can reset password. It probably is easier to reset password and send it for one time use in an email as long as it is hashed and stored.
What do you guys recommend?
32 comments
[ 5.5 ms ] story [ 70.9 ms ] thread2) Don't just hash. Use bcrypt, since it's probably got a library for you to use in your language (or database) of choice: http://codahale.com/how-to-safely-store-a-password/
Why don't you just send a link that includes your one time password? This will allow the user to choose a new one just clicking on the link and setting the new password, instead of going to your page, logging in and changing the password after that.
I'm not going to use/keep the generated password you send me, so just linking me to a page that lets me pick a new password to begin with works best for me.
This lets you send a link like www.mysite.com/resetpassword?userid=123×tamp=...&hmac=.... without having to keep a database backed copy of 'reset password' emails and tracking sent links.
You can make it so the link only works for say a few hours or any other combination of factors, the HMAC lets you 'sign' the URL you issue the user so it cannot be changed/forged, and you append a 'timestamp' argument to then let you determine if you consider the URL too old to take action on.
As a result, any future brief read-only compromise of their mailbox revealing that password may grant unauthorized access to their account.
Sending a time-limited link forces the choice of a new password. They might choose unwisely, but it would take an active compromise of their mailbox (intercepting a future reset-request) to leverage a password-reset to future compromise. If they do choose a bad password, that could be as bad as having your password sitting in their mailbox.
I get irritated like none other with stuff like that. It's just like emailing me my password in plaintext. If the user doesn't change the password, that email becomes a potential vulnerability. If a hacker gets access to that email, if they leave themselves logged in somewhere public, etc, etc. That password just became free game.
Plus, I have to copy/paste the password (what about mobile users, that's annoying), then I have to go reset the password myself which means digging through your site... THEN I have to again go retrieve the password to change it.
Plus you have the users that won't reset the password themselves manually... If you actually make it one time use only... then it's effectively the Exact same thing as just sending a reset link...
PLUS I can request a password reset for a random users account... locking them out until they check their email. That's horrendous, I can DOS your users trivially.
What type of token generation mechanism would you use to send with the link to identify a user or to make sure that the link is being requested by the right user.
The guid is set to expire after a period of time and requires that registered email and the key together. It won't allow login, only changing of their password.
No offense, but I listed reasons why it is more vulnerable.
>Also to make 'the link' more secure we need to verify the user identity.
What? No. That's completely wrong. You're inherently trusting the user's email address. Maybe make them answer a security question before sending the link, but otherwise, there's nothing else to secure.
If the user can't login, how do you plan to verify the user identity? And I have no idea what "need to store the user identity in the application" is supposed to mean...
The problem is, one person does this you pretty much have to change your code immediately if you disable an old password. And while I focused on the malicious, don't discount the accidental - my gmail routinely gets sent email meant for people who couldn't enter their own email address correctly when signing up for various things. If out of the blue a customer can't use their password and has to go find a new one to enter they aren't going to be too impressed even if it doesn't happen again.
Anyone using this to log in gets a prominent reset Your Password option after login.
This is, relatedly, how I log into people's accounts for support purposes, since I can generate your magic code for today at will.
1: http://dl.dropbox.com/u/9802610/Screenshots/06.png
1. replace their current hash with "LOCKED", plus some random noise.
2. generate a random string, and store the hash in a "forcedResetToken" field for the user.
3. email them a URL, part of which is the token.
4. when the link is activated, I look up the user account by the hash of the token, force them to choose a new pw, and remove the forcedResetToken.
That's the approach I take in my Wicket Quickstarter project (http://armhold.com/store).
Based on other comments I'm seeing, I'm now planning to also add an expiration of the token (say 24 hours or something).
A better lock-out approach is to disable logins for a period of time (say 1 minute)... i.e. as someone said above, you don't want to destroy the old password in case the reset was requested by someone else.
The token is included in the link sent to them (via email) that directs them to where they can reset their password.
The token is only valid for 24 hours and is unique so it can be authenticated against their email when they're resetting their password.
If someone logs into that account in the meantime, the token is removed and the link to resetting their password becomes invalid.