How to avoid open-redirect vulnerability and safely redirect on successful login (HINT: ASP.NET MVC

Posted by Brad B. on Stack Overflow See other posts from Stack Overflow or by Brad B.
Published on 2010-05-26T01:55:08Z Indexed on 2010/05/26 2:01 UTC
Read the original article Hit count: 770

Normally, when a site requires that you are logged in before you can access a certain page, you are taken to the login screen and after successfully authenticating yourself, you are redirected back to the originally requested page. This is great for usability - but without careful scrutiny, this feature can easily become an open redirect vulnerability.

Sadly, for an example of this vulnerability, look no further than the default LogOn action provided by ASP.NET MVC 2:

[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
    if (ModelState.IsValid) {
        if (MembershipService.ValidateUser(model.UserName, model.Password)) {
            FormsService.SignIn(model.UserName, model.RememberMe);

            if (!String.IsNullOrEmpty(returnUrl)) {
                return Redirect(returnUrl); // open redirect vulnerability HERE
            } else {
                return RedirectToAction("Index", "Home");
            }

        } else {
            ModelState.AddModelError("", "User name or password incorrect...");
        }
    }

    return View(model);
}

If a user is successfully authenticated, they are redirected to "returnUrl" (if it was provided via the login form submission).

Here is a simple example attack (one of many, actually) that exploits this vulnerability:

  1. Attacker, pretending to be victim's bank, sends an email to victim containing a link, like this: http://www.mybank.com/logon?returnUrl=http://www.badsite.com
  2. Having been taught to verify the ENTIRE domain name (e.g., google.com = GOOD, google.com.as31x.example.com = BAD), the victim knows the link is OK - there isn't any tricky sub-domain phishing going on.
  3. The victim clicks the link, sees their actual familiar banking website and is asked to logon
  4. Victim logs on and is subsequently redirected to http://www.badsite.com which is made to look exactly like victim's bank's website, so victim doesn't know he is now on a different site.
  5. http://www.badsite.com says something like "We need to update our records - please type in some extremely personal information below: [ssn], [address], [phone number], etc."
  6. Victim, still thinking he is on his banking website, falls for the ploy and provides attacker with the information

Any ideas on how to maintain this redirect-on-successful-login functionality yet avoid the open-redirect vulnerability?

I'm leaning toward the option of splitting the "returnUrl" parameter into controller/action parts and use "RedirectToRouteResult" instead of simply "Redirect". Does this approach open any new vulnerabilities?

Side note: I know this open-redirect may not seem to be a big deal compared to the likes of XSS and CSRF, but us developers are the only thing protecting our customers from the bad guys - anything we can do to make the bad guys' job harder is a win in my book.

Thanks, Brad

© Stack Overflow or respective owner

Related posts about asp.net-mvc

Related posts about authentication