If a previously registered user clicks on the password reset button during login, I want to send them an email with a reset password link.

I have three queries:

  1. How to add an expiry date to the URL link?

  2. How to structure the URL? I previously had not hashed passwords and sent a "click here" link with


    Now I have hashed all passwords how do I structure the URL? Do i still include the email&hashedpassword as above or hash the entire URL?

  3. I noticed with a well known UK site that when my wife requested my password to be reset I want sent the reset URL, but because one of my email addresses is auto-forwarded to my wife's email, she was able to reset my password and log into my account. Obviously i'm not too bothered in this instance, however I know many people who auto-forward their personal emails to work email addresses so technically someone could use a password reset URL to hack an account.

Is there a way round this...for example when you send the password reset URL, it only "works" if clicked from the mail client with that email address?

  • 1
    Oh man... what you are doing looks scary. Never send a password by the email. Don't even store the passwords anywhere. Hash them and keep the hashes secret (don't even think about sending the hashes anywhere!). Then, keeping this in mind, I believe you would find the solution by yourself.
    – smrt28
    Nov 19, 2015 at 14:19

2 Answers 2

  1. Don't do this. Add the expiry to the database, and check whether the token is still valid. If you add it to the URL, you are inviting people to modify it.
  2. Why are you sending a password out? The industry best practice is to send a short lived, single use token that takes users to a page that allows for entry of a password and a password confirmation, then sends them to the application login page to use the newly entered password to log in. That way, you avoid ever sending passwords from your server, meaning that only server compromise of some sort will reveal any passwords, whether user or system generated.
  3. There is not really a concept of "the mail client with that email address" - for example, I have an email account which I access from web browsers on various computers, an email client on my personal computer, and an email client on my phone. I also access other addresses with those same clients. The general way to ensure only the intended user can use such links is to keep the validity period as short as possible - an hour or so at most. There may be some users whose email takes longer than that to arrive, but remember that they are actively trying to log in at that point. If you tell them you have sent an email, they will probably go and look for it.
  • Also, ask some security questions before sending link so you're sure they've proved something they know, even if not old password. If you're worried about link misuse, ask security questions after user clicks link and before querying for new password. Nov 20, 2015 at 6:18
  • Also worth mentioning you shouldn't be able to send them their password. auth0.com/blog/hashing-passwords-one-way-road-to-security - In theory you should never have a user's password (yes, I know you can generate it pre-hash and send, but not best practice)
    – TCooper
    Aug 30, 2021 at 16:30

Don't write to the db if you can avoid it. Mozilla's bug tracker got hacked with a password reset writing to the db incorrectly.

Use an HMAC. Put the expiry time in the HMAC. Put the HMAC and expiry time in the url. Check the HMAC on request.

Here's a guide, including replay protection. https://neosmart.net/blog/2015/using-hmac-signatures-to-avoid-database-writes/

  • 1
    I wouldn't throw out the baby with the bathwater - databases were not the problem here - it was an implementation gotcha (the DB library not warning when a field is too small and truncating without warning). The advantage of using the DB is that the link can be expired once the password has been reset, reducing the exposure of the reset token. Nov 20, 2015 at 10:39
  • @SilverlightFox The HMAC method in the second paragraph is a valid method for expiring an URL without database.
    – billc.cn
    Nov 20, 2015 at 14:14
  • @billc.cn: Yes, but only in a time limited way, not in an after use way. It might be possible for an attacker to reset the password again using the same link before it expires. Using the database allows you to track what's out there and revoke reset links if necessary. Nov 20, 2015 at 14:21
  • The linked article is supposed to take care of replay attack though. (Personally I'd just append the current salt to the HMAC input and generate a new salt each time the password is changed.) And I doubt the necessity or practicability of revoking a password reset link. How many people remember to revoke those in a database-based solution anyways?
    – billc.cn
    Nov 20, 2015 at 14:35
  • @SilverlightFox read the article before dismissing it. It shows how to prevent replays as I already stated. Nov 20, 2015 at 19:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .