Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid open-redirect vulnerability and safely redirect on successful login (HINT: ASP.NET MVC 2 default code is vulnerable)

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?

Update

By limiting myself to controller/action routes, I can't redirect to custom routes (e.g. /backend/calendar/2010/05/21). I know that by passing more parameters to the LogOn action, I could get it to work, but I feel like I'll always be revisiting this method -- keeping it up to date with our routing scheme. So, instead of splitting the returnUrl into its controller/action parts, I am keeping returnUrl as-is and parsing it to make sure it contains only a relative path (e.g., /users/1) and not an absolute path (e.g., http://www.badsite.com/users/1). Here is the code I'm using:

private static bool CheckRedirect(string url) {
    try {
        new Uri(url, UriKind.Relative);
    }
    catch (UriFormatException e) {
        return false;
    }

    return true;
}

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

like image 268
Brad B. Avatar asked May 26 '10 01:05

Brad B.


People also ask

Which defense mechanism is considered most secure when it comes to protecting against unvalidated redirect attacks?

Preventing Unvalidated Redirects and Forwards Where possible, have the user provide short name, ID or token which is mapped server-side to a full target URL. This provides the highest degree of protection against the attack tampering with the URL.

Is open redirect a vulnerability?

Open redirect vulnerability in the software allows remote attackers to redirect users to arbitrary web sites and conduct phishing attacks via a URL in the proper parameter. Assume all input is malicious.

Which Owasp category does open redirect lie in?

Summary. Open redirects are one of the OWASP 2010 Top Ten vulnerabilities. This check looks at user-supplied input in query string parameters and POST data to identify where open redirects might be possible.


1 Answers

Jon Galloway wrote up an article with a solution for MVC 2 (and 1).

Here's the snippet that should help with your issue:

SECURED (original article updated 2014)

private bool IsLocalUrl(string url)
{
  return System.Web.WebPages.RequestExtensions.IsUrlLocalToHost(
      RequestContext.HttpContext.Request, url);
}
like image 73
Brett Veenstra Avatar answered Sep 22 '22 13:09

Brett Veenstra