In multiple systems I've built/supported I've seen user management do the following for password reset: generated a password reset token via some hashing method and email the link with token to user. Usually there are bits of information included into these tokens - user id, user security stamp, date, server name or machine key (I'm going with ASP.Net Identity framework now). When user follows the link with token, framework follows the same process to rebuild the token and compares the token with user-provided one. If tokens match - allow for password reset.

A lot of time machine-related parts of token change from the moment of token generation to the moment when user uses that token. I.e. IIS restarts and this can invalidate token in some cases. When web-application is spread on multiple servers (i.e. web-farm), chances of this token to be invalid are higher (i.e. machine keys are not synchronised between machines, etc.).

Now I'm considering a scenario where I store the generated token in the database, add a generation timestamp. And when user comes back with the token, I don't re-generate the token, but rather compare the stored token, validate the timestamp and allow/disallow password reset.

Given that token now becomes a password (though time limited), for a good measure I can treat it as password and store hash only.

I can't think of flaws in this scenario, but I'm sure there some. Given the implementation of this scenario is solid, what other issues might arise from storing the tokens?

  • server name or machine key ... uh, do they even have any guarantee that they'll hit the same server/machine anyways? If you're running a load-balanced app (or something with ephemeral instances, like in a docker container), you're pretty much guaranteed to hit a different process. All the information used should be configurable, and setup the same on each instance. – Clockwork-Muse Dec 6 at 19:47
  • Storing a token in a DB is a fairly common way to handle a reset. Just make sure you also store the username that is requesting the reset. There is an attack where an attacker has an account and requests a reset, received the email, then goes to that URL but changes their cookie (or a hidden form field) which specifies which user is being reset, and can reset arbitrary users to whatever password they specify. – Daisetsu Dec 6 at 20:43
  • @Clockwork-Muse Agreed, yet at least 2 system I've studied do this and no option to configure what goes into the token. – trailmax Dec 6 at 22:45
  • 1
    @Daisetsu I'd imagine storing the token in the same table as the account information, next to username/email/userId. And making sure all the items match (that was about "implementation is solid") – trailmax Dec 6 at 22:46

Store (user_id, expiration_time, hash_of_token). If hash function used is secure and tokens are unpredictable (with at least 128 bits of entropy), then there is no way for someone else to generate a valid tokens even if the attacker had read-only access to the database.

Specifically the hash function has to be resistant to preimage attacks. (SHA-2 and several other algorithms qualify.)

If the entropy behind randomly generated tokens is small then someone with read access can brute-force test preimages and potentially recover the token. Someone could also brute-force test potential tokens online (subject to rate limiting) with some probability of success dependent on how much entropy the tokens have and how many candidate tokens they can try.

High min-entropy inputs can be hashed with ordinary secure hash functions because it's not possible to test every possible input. Passwords, however, should be hashed with a dedicated password hashing algorithm (Argon2) because most passwords have very low entropy.

Those database fields, a CSPRNG, and a preimage attack resistant hash function are all that's strictly necessary, but see Secure Account Recovery Made Simple for additional information.

  • I'm not talking about implementing the whole user-management system myself (I'm not that skilled/mad). I was planning to rope in existing hashing and token generation from known/verified frameworks (ASP.Net Identity in most of my use-cases). My concern was with storing the token/hash of token, because that is not done for some reason. Rate limiting - good idea. Thank you for your input! – trailmax Dec 6 at 22:51

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.