0

I am building a new MVC app. Considering this "forgot password" flow:

1)You enter an email.
2)You press "send recovery password".
3)An email awaits in the inbox, pressing the link in it brings you to "new password" screen.

In phase 1, there is no limitations on the email you provide. (It may not even exist).

Are there any major security flaws with this flow?

Yaron Levi
  • 12,535
  • 16
  • 69
  • 118
  • 2
    What happens if a user account doesn't exist with that email address? – Dai Oct 15 '14 at 22:53
  • As I said there are no limitations. it could be any email – Yaron Levi Oct 15 '14 at 22:55
  • Is this why someone is logged in? otherwise what password for what account are you sending to the email address provided. if they are logged in why would they need to "recover" a password, sending passwords to any account other than the accounts email is a HUGE security risk IMO. If a attacker found a flaw they could send everyone's passwords to their own email address, if you only send to the accounts address the attacker would have to have access to that email account as well. – sa_ddam213 Oct 15 '14 at 23:14
  • @sa_ddam213 - It sounds like its a custom link that you get if and only if you enter a correct email address. Hopefully, if implemented correctly, the email entry form will not tell you if you entered an incorrect email. – Tommy Oct 16 '14 at 03:24
  • @Tommy, `there is no limitations on the email you provide. (It may not even exist).` I read that as I enter an arbitrary email address and it will send the password to that email, I'm still curious how this email is linked to the account that owns the password, there is not much detail in the question so I assumed the majority of my comment :), so I guess the user is already logged in, which was my main concern, but if they are logged in why the reset, why not use the asp change password feature, but I am sure he has his reasons – sa_ddam213 Oct 16 '14 at 03:43
  • @sa_ddam213 - yeah, fair enough - it is a pretty vague question. Hopefully OP will add some more information. We do something similar where emails are the users' username. You enter an email, we always show the "we sent an email msg". But, if it wasn't a valid email, we don't send anything in the background. If it was, you get a link (using a GUID) that is good for 30 min to change your password. After 30 min, you have to do it all again. But at no time do we ever say, that's not a known username. Too easy for someone to try and guess emails, one part of the login process. – Tommy Oct 16 '14 at 12:16

3 Answers3

3

While in discussions with someone under the question, I figured I would go ahead and post how we handle password resets using a similar flow, and point out where we try and prevent malicious intent. Here is our flow:

  1. On the login form, there is a link for "forgot password"

  2. The forgot password screen in a simple textbox, where you can enter your email address. In our implementation, the email address is the username, but it shouldn't matter as long as each user has a valid email address attached to their account.

  3. User enters an email address and presses "Submit".

    • IF the email address is associated with a valid account, we generate a GUID, store it in the password reset request table with an association to the requesting user account and set an expiration time of 30 minutes.

    • IF the email address does not exist, we do nothing. No email is sent to anyone.

  4. Regardless if the email address is correct or not, we always show a "Thanks, if the email address you entered is correct, you will be receiving an email shortly with instructions on how to reset your password". This is important as you don't want a bad user using this form to try and discover user names.

  5. The user receives the email and clicks the link. This takes them to a reset password screen (with a new password/confirm new password textboxes) if the GUID/link is still valid. If it is not, we show a "this reset key is no longer valid" if the key is expired or does not exist.

  6. After reset, user is redirected to login screen to login to the application.

Hope this helps. As others have said, use a good method to generate the reset password link, do not use any user identifying information in the link (someone could guess it, figure out your algorithm, etc).

Tommy
  • 39,592
  • 10
  • 90
  • 121
0

You should use https for the "new password" section to avoid someone trying to intercept that new password.

Make sure that the link you generate does not encode the email in anyway. Or else, if the hacker finds that scheme, then they could easily use that to generate the link and reset passwords for other users. I have seen some people pass the email or username in query strings which is terrible. Make sure you do the rest on a POST request.

It is also good to ensure that the link expires within a certain time window. Also, make sure there are good security restrictions on the kinds of password your system accepts (minimum number of characters, alphanumerals, special characters etc.).

Ensure you are logging the IP address where the reset request initiated and the IP address where the password was reset.

Lastly, make sure the new password form does not have any XSS (Cross Site Scripting) bugs in it and you can also add more protection by having an anti-forgery token in the form to prevent XSRF (Cross Site Request Forgery). There is ASP.NET MVC's AntiForgeryToken() helper method.

The no limitations on email is a bit weird - it could be used to generate spam for others. You said it is getting addressed in next phase, so it may be ok if your app is low profile and used in a bit more trustable environment such as small intranet or within a small business community.

Even there it could become a big problem if the users have typos in their email and wait for password reset emails to arrive while the system is sending a password reset email to someone else. Now, if this "someone else" resets the password for your user, you are in trouble. So you may also want to re-confirm the email on that page but if the intent of the user who got the email is malicious, that could also be guessed. Given this, it is probably better to add the check to see if the user exists in the first phase itself - to be fully secure.

govin
  • 6,445
  • 5
  • 43
  • 56
0

In my implementation, when the user enters an email (which is also the key/id of the account) in the forgot password screen, he gets a message "email was sent to the email you have entered: ". It might happen of course that the account is locked or does not exist. So you can issue another message: "account is locked or does not exist". but it is a bit risky since hackers can "harvest" accounts.

Community
  • 1
  • 1
OhadR
  • 8,276
  • 3
  • 47
  • 53