3 ms·
Don't store reset tokens in database, PITA and not scalable. Instead HMAC sign reset URL, using Rails' MessageVerifier class for example. The reset URL should
by gleb 14y ago
Don't store reset tokens in database, PITA and not scalable. Instead HMAC sign reset URL, using Rails' MessageVerifier class for example.
The reset URL should also expire in about a day, so include and sign timestamp as well.
And the way we know this is good advice is that most large sites do it this way already.
- trapexit 14y agoYou'll also want to implement some defense against short-term replay attacks (i.e. before the token expires). You could include a sequence number in the token, but this, of course, involves a database write, which is what you were trying to avoid in the first place. A better approach would be to store in the database the time that the user's password was last changed, and refuse to honor any reset tokens that are timestamped prior to that time.
- gleb 14y agoThat's a good point. You want the signed url to be one-use only. last_changed_password_at is a good solution, and a useful field to keep anyway.
- DenisM 14y agoBeter yet, mix in a random data field from the user record into the reset link (have it signed with HMAC), and regenerate the random each time reset it done. This way no reset link can be used twice, and no db writes are done when reset link is created.