PHP password recovery

14,558

Solution 1

You can not recover password that were hashed, neither should you.

What you should do instead is:

  1. Put some verification on the password reset request, like CAPTCHA.
  2. Create an one-time random code and send a link with it to user's email.
  3. Have this code expire in, say, an hour.
  4. Have this code expire immediately once used.
  5. On the link with the code, if it validates, allow him to change his password.
  6. Notify him that the password was changed, but do not send it in the email.

Solution 2

You don't 'recover' passwords. What you do is one of 2 things.

  1. Email the user a link to create a new password, overriding the current one
  2. Email the user a randomly generated password, then ask them to change it

Solution 3

My process is as follows.

1. User initiates a forgotten password request

The user clicks a forgotten password link and then redirected to a reset password form where they are asked to enter their registered email address.

2. Email address verified and token generated

After the user has entered their email address, the system verifies that it exists in the database. If the email address is valid then a token is generated and stored in the database with the users credentials.

3. Send recovery email

An email is sent to the registered email address containing a link to a reset form, the link includes 2 GET parameters including the token and the users unique ID stored in the database.

4. Reset password

After the user clicks the link they are taken to the reset form. The system retrieves the 2 GET parameters from the URL and verifies they exist in the database. If the token is verified to exist in the database with the user then the user may be shown the reset password form fields to enter a new password.

Security

I suggest using BCrypt (available since PHP 5.3) to hash the passwords and for additional security, perhaps use some sort of expiration for the token so it can't be used after a period of time.

Solution 4

You can create a new (and randomly generated) password for user, and md5 it , and then send user via email.

Share:
14,558

Related videos on Youtube

sehummel
Author by

sehummel

Updated on May 03, 2020

Comments

  • sehummel
    sehummel almost 4 years

    I realize that for security that passwords should not be stored in a DB as plaintext. If I hash them, I can validate them for login purposes.

    But if I want to set up a password recovery system, what's the best strategy since there is no undoing of the hashing?

    Could someone give me a brief overview of a good and secure strategy for storing and recovering passwords?

  • StasM
    StasM about 13 years
    sending passwords by email is a bad idea, since many people store emails pretty much forever and the information can leak out.
  • webbiedave
    webbiedave about 13 years
    @Stasm: He means a temporary password. The user then logs in to change it.
  • gen_Eric
    gen_Eric about 13 years
    @StasM: That's why you tell the user to change their password after logging in with this randomly generated one.
  • Eray
    Eray about 13 years
    @Stasm, ofcourse this password will be a temporary password. And it must be changed by user.
  • Incognito
    Incognito about 13 years
    @webbiedave what If I change the password instead of him?
  • Eray
    Eray about 13 years
    @user257493 , he can put a expiration date for temporary password. And user should change him / her temporary password after new password request
  • ircmaxell
    ircmaxell about 13 years
    Absolutely agree 100%. Never send any password (even a temp one) in an email. Granted, the one-time code is just as good as a password, but what else can you do...
  • StasM
    StasM about 13 years
    the code is as good as password only within limited timeframe, which makes it less dangerous.
  • k to the z
    k to the z almost 13 years
    md5 is cracked. Sha2 is better.
  • Marcky
    Marcky over 10 years
    What if, let's say Alice, register to your website(website.com) with a « fake » email([email protected]). Well, [email protected] (aka Bob) is an existing hotmail account and the owner is a bad,bright and active person. Bob sees an opportunity and activate Alice's account using the activation link he received. Bob is a bad boy, he really wants to log into Alice's website.com account and he knows how to do so. Bob ask for a password request, fill in its own email address, send the request, receive the activation link, click this link, update Alice's password. Finally, Bob can sign in.
  • StasM
    StasM over 10 years
    @Marc-AndréFecteau that's why you should never put in fake emails using real domains and accounts that may be created by somebody else. Create a gmail account with random long password instead and as soon as you're done with it you can throw away the password. Of course, if you ever need to recover the password for the site, you're in trouble :)
  • martinstoeckli
    martinstoeckli almost 9 years
    And store only a hash of the token in the database, otherwise an attacker with read access to the database (SQL-injection) can demand a reset for any email he wants, and because he can read the new token he can hijack the account.
  • sensation
    sensation over 8 years
    If you have SQLi vulnerability, you have a bigger concerns.
  • oelna
    oelna about 7 years
    For step 5: Is it ok to just generate a new password for the user and display it on the page, so fewer steps are required?
  • Stephen R
    Stephen R almost 6 years
    If you ever enter a fake email address, use example.com for the domain ;-)