11 ms·
Everything you ever wanted to know about building a secure password reset (2012)
- deeg 8y agoA good article but needs "(2012)" in the title.
- dang 8y agoGood catch! Discussion from back then: https://news.ycombinator.com/item?id=4280440 https://news.ycombinator.com/item?id=4280440
- sethammons 8y agoMaybe a feature request to save you some work. On submission, based on url, the site automatically lets the submitter know of prior submissions and if they choose to submit anyway, then (if they do) the first comment is an auto comment with links to previous discussions. Could also add a year to the lookup and have that gets auto added to the title if not already present.
- yetanotherjosh 8y agoGood, extensive write up. Note that correctly hashing passwords is a topic in itself and the short answer IMO is: use bcrypt. It should also mention that after a user changes their password, all login sessions should be invalidated. This lets a user who thinks their account/password may have been compromised prevent an attacker from using prior stolen sessions. This is accomplished by including a nonce (a "number used once" which is basically just a large random number) in the user record that is also included in the auth session, and verified on each request. It gets set to a new value on password reset, and thus invalidates existing sessions. (The active session issuing the password change should ideally have its value updated to the new value automatically, though.)
- hombre_fatal 8y agoOr execute sql "update active_sessions set expired_at = now() where user_id = $1" Expiring all sessions should definitely be a critical point on anyone's checklist when building a password reset system. Spotify didn't have this for the longest time and it was insane. Someone could buy a hacked account for $1 and get pretty much unlimited access. Though a special sort of infuriating softwaregore because you had to listen to what they were listening to.
- eknkc 8y agoIf you do not have a server side session store, only option is to use a nonce of some sort though.
- ben-schaaf 8y agoOr use a access/refresh token pair
- inopinatus 8y agoFor the extra conservative, rotate the nonce when the reset is requested.
- jerf 8y agoThat opens an attack vector where I can keep someone off a site by repeatedly requesting a password reset. You don't want to take any actions on an authenticated session as a result of actions of an unauthenticated user.
- inopinatus 8y agoYes I do. Sometimes the medicine is unpleasant but necessary. For many services, a malicious denial is better than an active compromised account, both in the material consequences and the opportunities for tactical management. We similarly also lock out after X failed login attempts.
- eknkc 8y agoMy current approach is to send an email with a temporary password which works for a single login and can be used to change the password. Original password still works. Temp password expires in 1 hour. It is basically a reset token but allows logins instead of loading up a reset form. One less thing to implement.
- eterm 8y agoFirstly, does your approach still invalidate the original password? If not that's really counter-intuitive. If I click a reset password button I want my password reset. Secondly, it sounds like you just give auth based on this token so you can re-use your password change screen, but if your password reset screen doesn't ask for the current password it really ought to do so to prevent the risk of left over sessions being used to hijack accounts (e.g. not logged out public machines, stolen cookies, etc).
- eknkc 8y agoWell the idea is that you do not click a reset password button. You click on a forgot password button so this gives you a temporary one to use. Your second point is spot on and I do ask for the current password. The temp password also works there. This is counter intuitive but not a security issue as you mentioned. I guess I can just skip asking the old password in case this particular session uses a temp password. I like reusing the password change form. But there is something more to this. Our logs show that if a user needs a password reset, they tend to need it more than once. So, there is a pattern that some of our users simply keep forgetting their password. It might be the nature of what we work on though, most of our users log in a once or twice a month. That pattern gave me the idea that if they are gonna keep forgetting it, maybe I should not force them to reset. Let them use a temp password every single time. It’s like what Slack does with “magic login link” stuff where you can elect to receive a login link via email instead of using your password during login. I guess branding it like Slack does might be better though.
- lisper 8y agoAnother criterion for a good security question: make sure everyone actually has an answer. I use a website that forces me to answer the following question: in what month was your first child born? It boggles my mind that someone at this company could fail to consider the possibility that a user of their site might not have children.
- xamolxix 8y agoOr that this information is known by other people too.
- inopinatus 8y agoI’ve similarly encountered mandatory security questions making US-specific cultural assumptions that simply do not translate internationally. “Name of your prom date” and “Favourite middle school teacher” for example.
- rhacker 8y agoThat's kinda funny to me. For people like me (and likely a lot of others that browse this site) the answer to how many children you have, is clearly "@#T%FGDw34dsd$"
- koolba 8y agoGiving answers like this over the phone to customer services reps is always a good laugh. CSR: “Wait, what’s your favorite city?” Me: “jeogusbw378fnsbwxwobp” CSR: “Is that in Europe?”
- logfromblammo 8y agoHuh. I only have "monkey ((( banana B4N4N4 banana" kids. I should probably switch to an automated child enumeration reminder program, to keep track of how many kids I had when I signed up for different accounts.
- stronglikedan 8y agoI have a pin code that I use to answer any and all security questions. I feel just as (in)secure using it versus the real answers, and I don't have to remember which "real" answer I chose when setting it (or whether I capitalized any words, etc.). I suppose I should start using random, incorrect answers and keeping them in my password manager, but I haven't got around to that.
- rhacker 8y agoThere are some slight enhancement that could be made, but would require gathering some additional info about your users: Start collecting IP addresses that the user has typically connected through. It's not OK to block that user from doing a password reset on an account with a new IP, but you could at least do some more internal alerts and secondary human checks (even if after the fact). Do all the other things in the article, but this would save some people. Another one would be to record in session storage or cookie storage, some randomly generated key, that is permanently recorded on the server. If a browser with any of those keys come back and initiates the forgot password script, again, you can lower the weapons a little after they get in.
- rraval 8y agoI disagree with the section titled "Username enumeration and the impact on anonymity". The author is trying to make the point that you shouldn't tell users that their username is invalid in a password reset flow. The author then goes further and recommends obscuring error messages during the login flow as well. I find this behaviour to be user hostile and not particularly effective at concealing anonymity. Under the same threat model, a suitably motivated third party can simply attempt to sign up with the same username, and you'll definitely have an error message if the user is already signed up (and that's besides the point that just because a username exists doesn't mean the person behind that identifier actually signed up, anyone could've done it). The author tries to justify their position by calling it a "slight usability tax" and "a small trade-off for an infrequent process", but my very short experience building a consumer oriented SaaS is that: 1. Password requests are frequent, even with ~5k users 2. Lots of people have more than one email address, and frequently forget which one they used for your service. 3. The support burden simply isn't worth the pseudo-anonymity.
- rhacker 8y agoTechnically there doesn't have to be live email validity checks on the sign up page- an email with the continue your signup with this link could be made available. OR an email saying you already have an account, do you need to reset your password?
- funkymike 8y agoIf you allow the full signup with the email confirmation after, then you are potentially sending the confirmation email to the wrong person. I have gotten sign up confirmations from other people using my email address. I have sometimes confirmed the registration, used the password reset to take over the account (since they use an email for the reset), then cancelled the account. If you aren't validating the email by sending an email that has to be replied to as part of the sign-up process (not after), then you are simply assuming that the email address was entered correctly without an opportunity for the person attempting the account sign up to correct it.
- timc3 8y ago
- njarboe 8y agoI sure wish my brokerage would allow me to turn off all online password reset options. They have an office near to me. If I forget my password, I would like to have to go to the office with my passport to reset it. This person should be high level and well trained so that social engineering is unlikely to work on them. I would be happy to do this and would prefer if they charged me $100 to reset my password this way. I don't day trade so I don't need a way to instantly reset my password. Many years ago I reset my brokerage password online and it was way to easy to do. The amount of money I have in the account is small enough that I have not seriously looked into other options yet. How do people with $5 million in a retirement account deal with the fact that someone could really screw you over by getting into the account? It might be somewhat difficult to get money out of the account, but if you are just trying to hurt someone, that should not be too hard. Log in. Use a million dollars to buy a bunch of a penny stock and the price will skyrocket as you buy. Then start to sell and keep selling as the price plummets.
- rhacker 8y agoI've actually wondered the opposite. If someone is charming enough, and has done some preliminary research on the bank's in-person screening, could they bypass security with something as little as a fake ID? Overall, I don't know if there is a perfect solution. Perhaps for banks we should pee-in-a-cup DNA test in addition to other tests. For a porn site we can do a poor mans email reset.
- _dark_matter_ 8y agoI believe that DNA tests fail the same reason that eye scanners and fingerprints do: they are not private. Almost anyone can get access to any of those 3, and then they just need to figure out a way to use it on the system.
- tedunangst 8y agoIs it really that easy to forge someone else's DNA and bring it to a testing facility?
- ggm 8y agoNobody said the answers to test questions have to be truthful or make semantic or syntactic sense. My mother's maiden name was trick cheese lobster
- protonfish 8y agoI really think secret questions are garbage. They grant minimal extra security for the cost of a huge hassle for customers. But the worst part about them is requesting and storing a significant amount of highly personal data. The likelihood of this data being breached and used against you is probably much greater than the security improvements it grants. Requiring many pieces of personal data to sign up for every fly-by-night web application is short-sighted and inconsiderate.
- jechamt 8y agoI agree completely. The article above is pretty dated (which is noted in the post), and so leaves out some better options for security that are available today, such as authenticator apps for 2fa. In the context of when it was published, it was an excellent and important stepping stone in security awareness, but working with the tools of the time. Now, we have better options and Troy Hunt (among others) has covered many of them in separate posts over the years.
- zdwolfe 8y agoEspecially when websites use secret questions as a means to reset second factor..
- BerislavLopac 8y agoI've been wondering how even having a password at all might be an antiquated feature. Most sites/applications today require you to have an email address (whether alongside a username or, increasingly, as the only identifier), and fully pass all verification to your email provider (by providing a password reset). In that situation, having a separate password for that site (and, presumably, one for each new one) seems a bit superfluous -- it should be enough to, instead, just enter your email and receive a unique one-time URL that will log you in if opened within, say, 15 minutes. Would this system be any more insecure than the present model of email + password + reset link?
- hjanssen 8y agoTumblr already gives you the choice to login via password or via a link sent to your inbox, although i have to admit i have only used this once to try it out - i am simply used to my password manager filling out the form in one click and i dont like to switch to my e-mail program everytime i log into something.
- sopooneo 8y agoIf you play this idea out to its extreme, and automate most of it, you get the first version of OAuth. https://support.smartbear.com/readyapi/docs/_images/projects/requests/auth/types/oauth1/about-flow.png https://support.smartbear.com/readyapi/docs/_images/projects...
- PretzelFisch 8y agoHow would you get that to work simply in a mobile app login flow?
- andreareina 8y agoIIRC, slack does (or did, ~3 years ago) exactly that. Either the email link is structured to cause the mobile OS to open the app, or the link leads to a page that then presents a link that opens in the app. In either case the link(s) contain a token that's valid for one use.
- astura 8y agoFuck "secret questions." I don't remember if i answered "88 Oldsmobile Cutlass Supreme," "1988 Oldsmobile Cutlass Supreme," Cutlass Supreme," "'88 Cutlass Supreme," "cutlass supreme," "1988 Cutlass Supreme," "Oldsmobile" or any other variation or misspelling. I don't remember if i had to tweek my answer to fulfill your dumb requirements (my favorite teacher has a special character in her name! Or the answer is 3 characters long and you have a minimum of four! My elementary school is numbered) I remember what street I lived on in middle school NOW, but I'll probably forget it in five years, I routinely forget much more relevant things. On top of that maybe I just don't want to tell every website I use who my childhood crush was. There's also the problem of most "secret questions" that are available being irrelevant for X% of the population. (ex. loners and people who didn't have a stable home life... they rarely include stuff like "who was your foster mom when you were 8?" Even the international crowd could have trouble with most questions.) I'm old enough and have enough online accounts (I have 246 accounts saved in my password manager) that i now just write "fuck you" for all the answers and put 'all answers fuck you' in my password manager. Because these questions stress me out way too much and I'm constantly bombarded with them. Answering them becomes a major pain point when everyone wants them. I've completely lost it with the damn "[not so] secret questions."
- duskwuff 8y ago> Or the answer is 3 characters long and you have a minimum of four!) "What is your favorite color? (Red is not allowed)"
- heyjudy 8y agoPassword storage (hashes only): PBKDF such as argon2i and salted. Limit the rate of both reset and reset re-email attempts (X within Y). Email the link that should expire on first use and set an expirable token param to complete the reset. Required login again to make sure people know their password. Form POST. Platform-Agnostic Security Tokens (PAST), not JSON Web Tokens (JWT) for headless API calls. CSRF (form hidden) token. Always https. Disable http.
- munchbunny 8y agoThis is really good stuff. I think the only thing I'd add is that, if you're building a login system anew, you should do 2-factor, and you should not use SMS codes. Use phone authenticator apps (time-based OTP's), FIDO U2F, heck, even Smartcards if you're paranoid. The best implementations I see are the ones that allow both phone authenticator apps for the people who don't want to carry a keyfob around or need to log in via their phones, and U2F for people who want their physical factor separate from their phone.
- tialaramex 8y agoOTPs are phishable. If you worry about SMS codes, you shouldn't accept OTP either, bad guys are just going to socially engineer your user into giving them a valid code. FIDO is the way forward, but having run into Microsoft's hapless first attempt (since they managed to get it to not work in anything except Edge on specific builds of Windows they also made it optional, so it actually can't make your security better. Brilliant) I have less confidence it'll ever be useful to the ordinary person... Still, it does protect my Google account.
- munchbunny 8y agoPhone based TOTP's are vulnerable to real-time phishing, but they still require you to sit there and enter the number on your phone. It still has to be your phone. That's not ideal, but that's substantially better than SMS where someone can take your phone number and your second factor is gone. No real-time requirement. That makes phone based TOTP the most secure second factor that is pretty much universally accessible to lay users (i.e. not buying a dedicated second factor device, and most people have smartphones). FIDO U2F isn't quite there yet in terms of universal support, but its design is definitely promising from a usability perspective. It's one technology I'm willing to hold my breath for.
- adrianhel 8y agoEverything you need to know about building a secure password reset: Cryptographically secure universally unique id -> email.
- deleted 8y ago[deleted]
- tzs 8y agoThe fluffy bunny option does not work for me, in either Firefox or Chrome on my Mac. Instead of replacing the image on the page, it just reloads the whole page with the boring humans. If you want to see the bunnies, it works to go the page at archive.org [1] and click the link there. [1] https://web.archive.org/web/20170819153353/https://www.troyhunt.com/everything-you-ever-wanted-to-know/ https://web.archive.org/web/20170819153353/https://www.troyh...
- amingilani 8y ago> the password is hopefully accompanied by a salt, each of which sit in their own columns Question: there's no real reason for the hash to be in a separate column, correct? Just that it's different per record?
- chias 8y agoCorrect. Many hashing functions designed for password hashing build the salt directly into the output string, in order to make it difficult to accidentally hash passwords without using a salt. On the other hand, if you're just using a bare hash function, you may find it convenient to store the salt in a separate column, if only to save yourself having to split on a separator character / character length in your application logic.
- amingilani 8y agoYeah, that's what I was I thinking. Bcrypt does that, or at least the implementation I'm familiar with seeing in Rails. The sentence threw me off there for a second. Thanks for the clarification.
- lucb1e 8y agoPlease don't use security questions: http://lucb1e.com/?p=post&id=65 http://lucb1e.com/?p=post&id=65 (coincidentally also from 2012) It's really weird to see this being advised. I thought we all agreed security questions are bad for lots of reasons.