如何避免开放重定向漏洞并成功登录时安全重定向(提示:ASP.NET MVC 2默认代码易受攻击)

Bra*_* B. 19 security authentication asp.net-mvc redirect

通常,当某个站点要求您在访问某个页面之前已登录时,您将进入登录屏幕,并在成功验证自己后,您将被重定向回最初请求的页面.这对于可用性非常有用 - 但是如果不仔细审查,此功能很容易成为一个开放的重定向漏洞.

遗憾的是,对于此漏洞的一个示例,只看ASP.NET MVC 2提供的默认LogOn操作:

[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);
}
Run Code Online (Sandbox Code Playgroud)

如果用户成功通过身份验证,则会将其重定向到"returnUrl"(如果通过登录表单提交提供).

以下是利用此漏洞的简单示例攻击(实际上是众多攻击之一):

  1. 假装成受害者银行的攻击者向受害者发送包含链接的电子邮件,如下所示: http://www.mybank.com/logon?returnUrl=http://www.badsite.com
  2. 在被教导验证整个域名(例如,google.com = GOOD,google.com.as31x.example.com = BAD)后,受害者知道链接是正常的 - 没有任何棘手的子域网络钓鱼行为上.
  3. 受害者点击链接,看到他们实际熟悉的银行网站并被要求登录
  4. 受害者登录并随后被重定向到http://www.badsite.com看起来与受害者银行的网站完全相同,因此受害者不知道他现在在不同的网站上.
  5. http://www.badsite.com 说"我们需要更新我们的记录 - 请在下面输入一些非常个人的信息:[ssn],[地址],[电话号码]等."
  6. 受害者,仍然认为他在他的银行网站,堕落的策略,并为攻击者提供信息

有关如何维护此重定向成功登录功能的任何想法,但避免了开放重定向漏洞?

我倾向于将"returnUrl"参数拆分为控制器/动作部分并使用"RedirectToRouteResult"而不是简单地"重定向".这种方法是否会打开任何新的漏洞?

更新

通过将自己限制为控制器/动作路线,我无法重定向到自定义路线(例如/backend/calendar/2010/05/21).我知道通过将更多参数传递给LogOn操作,我可以让它工作,但我觉得我将永远重新审视这种方法 - 使我们的路由方案保持最新.因此,不是将returnUrl拆分为其控制器/动作部分,而是保持returnUrl as-is并解析它以确保它仅包含相对路径(例如/users/1)而不是绝对路径(例如http://www.badsite.com/users/1).这是我正在使用的代码:

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

    return true;
}
Run Code Online (Sandbox Code Playgroud)

旁注:我知道这种开放式重定向与XSS和CSRF相比似乎不是什么大问题,但我们的开发人员是保护我们的客户免受坏人的唯一事情 - 我们可以做任何事情来制造坏人'努力工作是我书中的一个胜利.

谢谢,布拉德

Bre*_*tra 9

Jon Galloway撰写了一篇关于MVC 2(和1)解决方案的文章.

以下是应该帮助您处理问题的代码段:

SECURED(原始文章更新2014)

private bool IsLocalUrl(string url)
{
  return System.Web.WebPages.RequestExtensions.IsUrlLocalToHost(
      RequestContext.HttpContext.Request, url);
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*vey 0

只要您使用使用控制器和操作参数或路由名称的重定向变体之一,只要您对控制器方法有足够的安全控制,就应该没问题。

这个概念是,无论您使用什么进行重定向,都必须经过路由引擎并通过匹配路由进行验证。

但我怀疑真正的漏洞是跨站脚本。除非您的恶意用户可以将一些 Javascript 注入到页面中,否则他们无法操纵返回 Url 或其任何参数(因为您以其他方式控制所有服务器和浏览器代码)。