views:

642

answers:

14

I was wondering what would be the safer option when users have forgotten their password

  • Send a randomly generated new password to the email address (all email addresses in my database are confirmed to work).

Or

  • Send an email with a link that expires within a certain time frame where the user can reset their password.

Aside from the fact the latter uses an extra table, what do you think is safer/better practice?

+7  A: 

Send an email with a link that expires within a certain time frame where the user can reset their password.

That one, definitely.

E-mail is always in the clear (potentially your site connection may not be), and can touch more machines. Keep passwords out of e-mail. The temporary reset token also means that if the mailbox is hacked later on, the token is of no use any more.

Aside from the fact the latter uses an extra table,

It doesn't have to. You can generate a cryptographic token authorising a particular user to reset a password within a certain time frame; no extra data required.

An example using hashing:

details= user_id+' '+token_expiry_timestamp
hash= sha1_hash(server_secret+' '+details)
token= details+' '+hash

then send the token to the user as part of the clickable URL in a mail. When you receive a click back, work out what the hash should be for that user and time with your server-side secret, and check that against the passed-in hash. If it matches, it must be a password request you signed earlier.

user_id, token_expiry_timestamp, hash= token split on ' '
details= user_id+' '+token_expiry_timestamp
if sha1_hash(server_secret+' '+details)!=hash
    complain
else if token_expiry_timestamp<now
    complain
else
    allow password for user_id to be changed
bobince
I think you're misunderstanding the sent password bit. It'd send a new, randomly generated password, not the old, real password. The user would then have to pick a new password once they're in. No master password sharing.
ceejayoz
OK, but done that way you couldn't change the *actual* password to random on a password-request because that would be an obvious DoS issue. You'd have to have two passwords, which in the end isn't much different to having a separate reset token.
bobince
nice solution. I am extending this further in my post.
Gladwin Burboz
Yes, bobince, you'd make a second, temporary password. Same as having a token. My point is that they're exactly the same security wise.
ceejayoz
+1  A: 

As long as the URL doesn't ask for a password or some such, it still is better than the randomly sent password but only because it doesn't leave the password in plain text in an Inbox.

In other words, the link reduces the window of opportunity.

Vinko Vrsalovic
Why? The random key in the URL is, in essence, a password, and is just as plain text. They're the same.
ceejayoz
@ceejayoz: Because the URL renders itself invalid when it's used. The email password has the potential to never change. They would really be the same if logging in with the sent password forces you to change it AND the random password sent has an expiry date.
Vinko Vrsalovic
@ceejayoz: Consider the case of someone reading over your shoulder. If they see an email which says "Your new password is 'secret'" they can run off and log in as you. If they see a link, they are less likely to be able to remember it and don't have the opportunity to actually click it. If you can remember strings like `2b574cb4478ce2f65b00d111a38631833c1f6ba696224896ee4abccffac38fe3d3e0dfbd1984ed0bdae3b6293b94fd7b` then more power to you. Additionally, if the email is sent in HTML format then a link that reads 'click here to reset your password' is considerably less helpful.
Duncan
If someone's reading over my shoulder, I'm probably resetting my password right there and then. I've never seen a reset link that long, either. There's little functional difference.
ceejayoz
There is little functional difference to you, who would change the password. Not everybpdy will.
Vinko Vrsalovic
+3  A: 

Obviously the latter is much safer. Email is like a postcard. Pretty much anyone can read it who wants to. Also, once the password is changed, send an email to close the loop.

wallyk
The link is also in an email, were it to be intercepted and if it doesn't ask for some authentication, it is similarly insecure.
Vinko Vrsalovic
+21  A: 

If you send an email containing the password, it means :

  • The password will go through some networks (unencrypted) and could be "seen"
  • The password will stay in the user's mail box
    • Which can be hacked
    • And just any one who has access to the computer might take a look

So, sending the password in an email doesn't seem that safe...


As a user, I would feel my password is "safer" with the link that contains some kind of token and expires after a while.

That "expires after a while" part is important, btw : it makes sure that if someone clicks on the link after some time (for instance, someone who accesses the user's mailbox), the link will not be used to generate a new password.


Of course, this means I won't be able to just "search in my mail box" to find the password -- but I can always ask for a new one I have forgotten it again ^^

Pascal MARTIN
A random password, not the user's original password (which should never be stored in a retrievable form, anyways). A link is as good as a password in this situation.
ceejayoz
except that the link as a short lifetime *(cannot be used after a while)* ; while the password sits in the user's mailbox forever.
Pascal MARTIN
Or you could send the user a temporary password that expires. Once the user logs in with the temporary password, you immediately prompt them to change it.
Kevin Pang
@Kevin Pang: You'd then be rendering both methods to be equally (in)secure. Why would you prefer the password?
Vinko Vrsalovic
Huh? Making the temporary password expire makes it just as secure as the link, so it makes no difference which one you pick.
ceejayoz
my point exactly...
Vinko Vrsalovic
@Vinko Personally, if given the choice between an insecure password and an insecure link, I'd rather have the insecure password since I don't like clicking on links within e-mails. If you agree that neither solution is more secure than the other, then I'd take the expiring password over the expiring link.
Kevin Pang
Also changing the password when the original request is done means that the user can no longer log in with the original password. That's an easy (temporary) DOS attack right there, because I can just click the "forgot password" with button your user name and as long as you don't check your mails you can no longer log in.
Joachim Sauer
@Vinko : The advantage to the link over the password is that after following the link, you can then prompt them for additional information in an attempt to prove their identify, whereas the pasword lets them straight in.
Joe
@Joe: You could ask for the same kind of information after the first successful login with the new password. There really is no practical difference...
Vinko Vrsalovic
@Vinko: If it's a password for a webapp, perhaps, but maybe not if you're changing a password for other types of systems (eg. radius, kerberos, ldap ... where it's an authentication service that you don't control interaction with the user)
Joe
@Joe: Fair point, I was thinking only about apps with UIs.
Vinko Vrsalovic
+8  A: 

Rather baffled by the other answers here. They're exactly the same. Both give access to the user's account, both are sent in plain text, and both are in common use. Pick whichever you prefer.

Enforce an immediate password change once they use the link/password, and have the link/password expire after 24-72 hours.

ceejayoz
I agree with you completely, they both seem the same. Most of the other answers are assuming that it isn't possible to expire a password or to have a second temporary password. The only thing I would change is the length of time. I think 24 - 72 hours is way too long. To be honest, 10 minutes should be enough time.
Peter
I've had e-mails take an hour or more to show up in my inbox from certain senders.
ceejayoz
+1  A: 

I've always been a fan of setting a hashcode and giving them a link.

Sending an email to the user afterwards letting them know they requested a password recovery link, and after they set one telling them their password was changed is usually a good courtesy in case there was a violation.

A user will very quickly react to an email saying their password was changed if they didn't mean to do it.

Unfortunately there is no real "SAFE" way. Security Questions an pins can help but are never truly secure.

Chris
+5  A: 

One difference that people seem to have neglected is that - taking a web application for example - a password reset option is usually open to anyone who accesses a site and knows the username/login of the account that they want to reset the password for.

By sending a link in an email that the user has to click in order to be able to reset their password, you avoid letting users accidentally or maliciously reset other people's passwords - all that will happen is they receive an email that ends with, "If you did not ask to reset your password, please ignore this email."

Even if it's not a security risk per se, resetting passwords without confirmation could be a major annoyance.

Latedeveloper
Well OP might have considered this issue already. Most sites send you an email with a URL to reset or issue a new password. Then you get a second email with what OP is deciding. We can just ignore the first issue and assume OP has considered it.
Pyrolistical
If OP had considered it why on earth would they need to send an email in the first place. The only reason to use email is to verify that the person requesting the access change has, at least, access to the account used to create the credential.
Andrew Neelands
A: 

Everybody except for ceeyajoz is using flawed logic. Its hard to think about security.

Both cases use of email which is in plain text. Both are equally insecure when email gets hacked.

It doesn't matter if the URL expires since the email is hacked the hacker can just request for another password reset URL. If the temporary password has changed, the hacker could just request a new one. Either way you are screwed.

So I say just send the password, this way its one less step for the user to pick a new one.

EDIT When I said "send the password" it was in the context of the OP where you send a new random password.

Pyrolistical
Then anyone can go to the site and reset other peoples passwords.
Frank Schwieterman
??? How? You must be misunderstanding me
Pyrolistical
If the email has been compromised, then either way is insecure. However, if you send the password you have just given the hacker potential access to numerous sites since many people use the same password, even if those other sites don't expose the password or are registered with different email addresses. Sending a link mitigates the damage done. It is safer, not necessarily safe. I guess your comment about everybody except ceejayoz using flawed logic means you are using flawed logic?
Duncan
@Duncan - No one is suggesting sending the old password... we shouldn't even know what the old password is. We're sending a new password, which, conterintuitively I'll admit, has exactly the same effect as sending a reset link.
CurtainDog
@CurtainDog: I misread 'send the password' to mean the current password, not a new random one. Nonetheless, if you're not forced to change the password then the link is safer, unless the random password is extremely random, in which case it might as well be a token. And if you are forced to change the password, it's not one less step. In terms of laziness, sending a link means one click to get there, sending a password means going to the web site, going to the login screen, and copying and pasting the password out of your email. So a link requires less user effort :)
Duncan
It should never be **possible** to even send the old password, @Duncan. Hashing is a must.
ceejayoz
+1  A: 
  1. Send them an email with a random, one time use, password.

  2. Force them to change the password when they first arrive.

  3. Notify them that they changed their password.

Sending the random password is as much of a risk as sending the link. i.e. anyone can get the email first and log in as the user the first time.

By forcing the change, whoever gets their first can not get there again without setting a password.

Notifying the user of the change tells them that the password has been changed, and this can happen before the attacker can actually log in and change the notification email.

So, if someone were to get to the site first, the original email to the user will no longer work, as the original password is no longer valid. Also, they'll be notified of the password change.

This provides an opportunity for them to notify sys admins when they show up and find they can not log in to their account.

None of these stop the ability of a person intercepting the email and getting SOME access, but at least it lets the original, vested, user know something is amiss.

Will Hartung
+1  A: 

Some have stated that both are equivalent - this is not true for following reasons:

1) With reset link if attacker has access to email and consequently uses reset link to change password, they will alert user even if the actual reset email and notifications are deleted by attacker. With mailing password if user requests reset and attacker sees the random password (even much later), then attacker can access user's account on your site without alerting user.

2) Also if you mail a password the user may be tempted to re-use the password on other sites and attacker with access to email has access to other sites even if the other sites were not vulnerable to account take over via account recovery.

With both random password sent in email and reset link, if attacker controls user's email, they have access to user's account. What you can do in this case, depends on how many handles on the user you have - for example, if you have their primary and alternate email address, then you should send notifications to both email accounts when reset is requested and used or if they have a phone, you could send them a text in addition to email, etc. You can monitor usage itself but that is harder.

A couple of other issues:

Can the link be used multiple times? Apart from expiring and having unpredictable value (with attached MAC so it can be verified without server state), you may want to have an internal alert go off if an attempt is made to reset password on an account multiple times (register success/failure, remote ip address, timestamp, etc) and abort after first and put the account in some inactive state.

It would be a good idea to see how much abuse is happening to see if you need more defense mechanisms to prevent account takeovers via your account recovery flows (depends on the value of an account).

Also very important in this case to keep up-to-date on email addresses and other contact information if you can (email addresses do get recycled when not used) and how email address or other such information can be updated/added and notifications.

As always make sure your notifications (text, link, landing page) don't make it easy for phishers.

Some of these issues of course may not be very relevant unless you have a large site.

mar
+1  A: 

Send them a link so they can later reset their password. This forces them to confirm somewhat its actually their account they're resetting the password for. If you reset the password without sending an email, anyone can log in to the site and reset anyone else's password. This creates a denial of service type vulnerability.

Frank Schwieterman
A: 

i agree with will's process.

however if you only choose between the options you have given, although both options are essentially the same in that you're sending information via email, i think the latter is a more common method.

if a hacker was to request a new password, the user's old password would no longer work. at least with the latter option it doesn't actually change any user details.

benpage
You don't disable the old password. That'd be horrifically unusable. You set a second, temporary password. The user can still log in with their real password (preventing abuse), or using the temporary password allows them to set a real password.
ceejayoz
A: 

Although I may be repeating some answers, I feel compelled to respond because we recently had some issues with faulty password recovery tools. One of my coworker's personal accounts was compromised which allowed our google hosted domain apps to be compromised. Due to undeleted plaintext passwords and stupid password recovery questions that were googleable other accounts were compromised as well.

Suffice it to say, I am a strong adherent to emailed links that expire after 4 hours. I sat there for 4 hours logging into one of our accounts after receiving the link making sure it was still uncompromised. 24-48 hours would be waaaay too long to have to do that. 4 hours was too long. A randomly generated password that the user is required to change upon next login is second best, but it is completely dependent on the user actually logging in. The password is changed permanently, whereas if the user does nothing with the link, the password will not be reset.

There is no perfect solution against a dedicated individual who wants to compromise your system. There are better solutions than others.

Elizabeth Buckwalter
A: 

Extending from bobince's solution... Here user is required to reenter userId and token on password reset page.

On request for reset password page

urserId = Input userId
token = Randomly generated token (or one time password)
tokenExpire = Decide token expiry date/time
Store in DB tokenExpiry for this urserId
urlToken= MD5 hash value of (urserId + token + tokenExpire)
pwdRestURL = server pwd reset url + "?urlToken=" + urlToken

Send above generated URL and make sure you do not 
    include either of userId or token in email

Display token to user (This is to be used on password reset page)

.

On password reset page (using above pwdRestURL URL)

urlToken = Token from URL request
userId = Input userId
token = Input token
tokenExpiry = tokenExpiry from DB for this user
resetToken = MD5 hash value of (urserId + token + tokenExpire)
IF
    resetToken == urlToken 
    AND tokenExpiry for user is valid
THEN
    Clear tokenExpiry
    Allow user to change password
ELSE
    Display Error
END IF

.

Advantages of above approach:

  • Even if email is some how exposed in network, no one can reset password without knowing the userId and token.
  • Token has an expiry period
  • No clear test personal information is relayed over email
Gladwin Burboz