7 ms·
Any good reference to look at in terms of best practices for password reset ?
by codegeek 14y ago
Any good reference to look at in terms of best practices for password reset ?
- danielweber 14y agoAsked this before, and got this nice summary from 'patio11 http://news.ycombinator.com/item?id=4940102 http://news.ycombinator.com/item?id=4940102
- tptacek 14y agoNo; every implementation fails in some new and creative way. The implementation I feel most comfortable with: 1. Generate a 256+ bit cryptographically secure random number and base64 it to create a token. 2. Record that token in your database, timestamped, along with the user account for which the token was requested. 3. Mail the token to the user's email address. 4. When the user returns to the site after recovering the token, use that token to look up their account from the database. 5. Expire tokens within single-digit hours so users don't end up accidentally banking password-equivalents in their email accounts. 6. When a user changes their password or requests another password reset, expire all tokens already associated with their account. I would also recommend: (a) Not having any in-band administration functionality in your application; instead, have a separate admin application, attached to the same databases, available only on a VPN. (b) Require 2-factor authentication (such as Duo Security) for both admin VPN access and admin login. A knock-on benefit of (a): your admin functionality is easier to build, because it doesn't have to do the UI/UX chinups your normal exposed app code has to do; crappy looking admin screens nobody but your employees see are generally fine.
- codegeek 14y agoAny opinions on the itsdangerous module ? I am using it currently for a side project to generate reset URLs. http://packages.python.org/itsdangerous/ http://packages.python.org/itsdangerous/
- tptacek 14y agoIf you have to use any cryptography other than "generate random number" to implement password reset, you should be ready to cough up $7-14k for a professional security assessment. I'm not trying to drum up business. I would strongly prefer that you not try to be clever with this feature. Or, you can ignore the audit and just be the subject of a blog post like this sometime in the future.
- wulczer 14y agoI commented on the other thread, but will repeat here: I really like how Django handles password resets. No nonce is generated and nothing is stored. The user is emailed a link with her user ID and a token that's a hash of (last login timestamp + the user's ID + the user's (hashed) password + current timestamp). The token is HMAC-signed with the site's secret key. This way the token automatically expires if the user either successfully changes her password (the password hash will change) or manages to log in (last login timestamp changes). It seems that in Django password reset tokens are valid forever, but it would be trivial to add the current timestamp to the token and include it when computing the HMAC signature; then the password reset form would check if the token has been generated recently enough. I like this method because you never need to touch the database and store tokens; it's all fairly stateless.
- tptacek 14y agoIf you want to get clever to avoid touching the database --- which is why every broken password reset feature ever conceived decided to get clever --- you should have your code assessed professionally. I'm not telling you it's impossible to build a secure password reset that doesn't simply store a token in the database. I'm just saying the cost/benefit payoff is probably not there. Personally, I have this particular bit of appsec down cold, and if I was building a new app, I wouldn't even think about it: I'd use a random token and save it in the database.
- wulczer 14y agoI just gave django.contrib.auth.tokens a read and shared my opinion on it :) I wouldn't roll my own password reset feature if I can just take the builtin one from Django, which is what I did.
- tptacek 14y agoThe good thing about taking your web stack's password reset feature, if it has one, is that you're probably going to find out quickly if there's a bug discovered in it. Note though that that's not the case for 3rd-party password reset libraries or, more likely, the all-purpose security library that provides it. I'd be very wary about using a 3rd party library for password reset unless they've got a credible for story for it having been reviewed. Django: Good. 3rd Party Library: Less Good Just Using A Random Token: Good Cryptography: You Will Perish In Flames
- pygy_ 14y ago> 2. Record that token in your database, timestamped, along with the user account for which the token was requested. The token is a password equivalent, and should thus not be stored in clear (use scrypt or a similar scheme).
- tptacek 14y agoNo, this is unnecessary. An attacker who can pull tokens out of the database already has a terrible vulnerability and can probably avoid the need for passwords altogether. I've tested many many many many applications in the last X years and not one of them has ever done this, nor would I ever recommend that they do it.
- pygy_ 14y ago> [...] and can probably avoid the need for passwords altogether. Probably, yeah... In the case they only have read access to the token DB, and need write access, or read access to another part of the system, it becomes an attack vector. It is not a cargo-cult measure, and it doesn't add much complexity (just re-use your password encoding logic). The same goes for session tokens, BTW. > [...] nor would I ever recommend that they do it. Maybe you should reconsider that. I know who you are, and how knowledgeable and experienced you are, but in this case I think you're just wrong.
- tptacek 14y agoI have never, ever, ever, ever seen an application one-way hash their reset tokens to prevent disclosure of them from their database. That's all I'm going to say here.
- pygy_ 14y agohttp://en.wikipedia.org/wiki/Argumentum_ad_populum http://en.wikipedia.org/wiki/Argumentum_ad_populum A cargo cult is not an argument.
- 14y ago
- wglb 14y agoWith respect to (a), for the applications that require some level of admin function, I say to not allow password reset for those higher-level priv accounts. And with 6, i suggest expire at step 4.