HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

"Forgot password" functionality

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
forgotfunctionalitypassword

Problem

I want to implement the "forgot password" functionality in Asp.Net MVC 5. Here is the code flow:

  • Take user email ID



  • Let the user enter the token received in his email inbox



  • If the token matches then redirect for password reset page



  • Set the new password



Please tell me where I can improve.

```
public ActionResult ForgotPassword()
{
return View();
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ForgotPassword(ForgotPasswordMV viewModel)
{
if (ModelState.IsValid)
{
if (SecurityHelper.SendEmail(viewModel.Email))
return RedirectToAction("VerifyToken", new { email = viewModel.Email });
ModelState.AddModelError("Email", "Email not found");
}

return View();
}

public ActionResult VerifyToken(string email = null)
{
VerifyTokenMV viewModel = new VerifyTokenMV
{
Email = email,
Token = ""
};

return View(viewModel);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult VerifyToken(VerifyTokenMV viewModel)
{
if (ModelState.IsValid)
{
if (SecurityHelper.VerifyToken(viewModel.Token, viewModel.Email))
return RedirectToAction("ConfirmPassword", new { email = viewModel.Email });
ModelState.AddModelError("Token", "Token does not match");

}

return View();
}

public ActionResult ConfirmPassword(string email = null)
{
ConfirmPasswordMV viewModel = new ConfirmPasswordMV
{
EmailID = email
};
return View(viewModel);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ConfirmPassword(ConfirmPasswordMV viewModel)
{
if (ModelState.IsValid)
{
if (viewModel.Password == viewModel.ConfirmPassword)
{
SecurityHelper.UpdatePassword(viewModel.EmailID, viewModel.Password);
TempData["Message"] = "Your password has been updated.";
return RedirectToAction(action, homeController);
}
ModelState.AddModelError("", "Password does not match.");

Solution

Is this secure?

No. It isn't secure because you can change anyone's email address on the last step. To do so, all I need to do is change the emailId stored in the hidden field (for example, using my browser tools).

In the final step you must verify the token. You don't need step 2 at all.

There are two requests you need once you have your reset token. Typically you'd click a link in the email.

GET passwordReset (pass in the reset token)

POST passwordReset (pass in the reset token and the new password)

Use the reset token to look up the email that you're changing the password for. The token should be time limited, long and random to avoid guessing.

Context

StackExchange Code Review Q#161566, answer score: 3

Revisions (0)

No revisions yet.