6

I am working on a C# ASP.MVC 4 project making use of the DefaultMembershipProvider and I am trying to come up with a user friendly way to recover / reset a lost password.

My first attempt was to have the user provide their username (which is a valid email address) the application would then generate a random password (meeting our requirements), that password is then emailed to the user.

My ideal solution would be that when a user clicks the forgot password button. They are asked for their username which when provided would cause an email to be sent with a URL (this URL will also have an expiration date attached to it). This solution also resets the users password inside then application (before sending the email). When the user clicks on the URL, they are automatically logged in and sent to the change password form. Are there problems with this solution?

For configuration I have the following values set:

<membership defaultProvider="DefaultMembershipProvider">
  <providers>
    <clear />
    <add name="DefaultMembershipProvider" type="System.Web.Providers.DefaultMembershipProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" 
         enablePasswordRetrieval="false" 
         enablePasswordReset="true" 
         requiresQuestionAndAnswer="false" 
         requiresUniqueEmail="false" 
         maxInvalidPasswordAttempts="5" 
         minRequiredPasswordLength="6" 
         minRequiredNonalphanumericCharacters="0" 
         passwordAttemptWindow="10" 
         applicationName="/" />
  </providers>
</membership>
flip
  • 391
  • 1
  • 7
  • 15

2 Answers2

6

First of all here are two must read [I repeat, MUST read]:

  1. Everything you ever wanted to know about building a secure password reset feature
  2. You're Probably Storing Passwords Incorrectly

With that said, OWASP has some guidelines about how to implement authentication, you can get started at their Authentication Cheat Sheet and for your particular case the Forgot Password Cheat Sheet. Which is also arguably a must read. If you are not going to follow OWASP, I hope it is because you decided to, and not because you didn't know any better.

Anyway, the best abstract is the image that follows (which is taken from the first link above), if you are going to remember only one thing, let it be this:

Password reset workflow

Theraot
  • 31,890
  • 5
  • 57
  • 86
2

There is a flaw in your approach - you write that sending the email resets user passwords. This would be misused easily to reset passwords for any of your user by just anyone, assuming that the misusing person knows the login. In other words, I would just sit in front of your system and block other users' accounts by just clicking "i don't remember my password" and providing their user names.

So, you don't have to reset anything. The approach would be create a store for unlock requests (can be a table in a database) where each request is identitied by a guid and has an expiration date, the username and a flag to mark if a request has been used. When you send the email, you create a record in this request store and the email contains a link with the guid (note that no other information is required in the unlock email).

Then, when someone clicks the link in their email, at the server side you have the guid of the request. From your request store you read the expiration date, the username and the information if the link has been used before. Then you present a form where the user provides his new password.

Comparing to your approach, this has the advantage of not interferring with existing passwords. Also, hiding all the information at the server side and exposing only a guid to the user has the advantage of not exposing potentially sensitive information to the client (like the link expiration date).

Wiktor Zychla
  • 47,367
  • 6
  • 74
  • 106
  • That is indeed a flaw. I see that the codeproject.com got around this by introducing a captcha before resetting / emailing the new password. – flip Nov 11 '12 at 13:35
  • That is why instead of reseting / emailing a new password, you email a token that allows to change the password. There is still a flaw in the cp approach if it works the way you said - I can easily force cp to reset and email the new password to any user, I WILL pass the captcha as I am a human but the user account will be unavailable for him. IF he checks his email, he gets the information but what if the doesn't check his email? – Wiktor Zychla Nov 11 '12 at 14:16
  • Yes, the flaw is still present even when a captcha is introduced. A captcha is just another hoop that the user or abuser has to jump through. I am going to go the route of the token, seems like the most logical and water tight solution. – flip Nov 11 '12 at 14:39