登录页面的防伪标记

20

我在我的登录页面上实现了防伪标记。

现在有一个用户在键盘上按下返回键,当他们填写凭据后再次点击登录按钮时,他们会得到错误页面。

是否有更好的方法处理这种情况,比如将他们重定向到新的登录页面?

登录页面是:/account/logon

如果登录细节成功,用户将被重定向到:Home / Index 页面,其中用户按下按钮返回。


用户按下退格键时在哪个页面? - Darin Dimitrov
4个回答

23

不要在登录页面实现ASP.NET AntiForgeryToken。该令牌基于用户名等标准,而登录页面假定攻击者已经具有访问系统的凭据,以便能够利用该页面上的csrf。

但是,在登录页面上应该使用某种形式的CSRF保护 - 请参见https://security.stackexchange.com/a/2126/51772


15
我对@AdamTuliper的回复很有信心,直到我偶然发现这个链接 - http://security.stackexchange.com/questions/2120/when-the-use-of-a-antiforgerytoken-is-not-required-needed。其中提到了这篇论文 - http://www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf - 是一篇非常好的阅读材料。 - aunlead
2
我应该在回答中加上“在asp.net mvcs实现防伪令牌时”的前缀,因为它是基于登录名的。来自匿名用户的令牌可能无法提供所需的保护-我需要测试一下,因为它在大多数情况下都与登录名相关联。 - Adam Tuliper
4
危险 - 不要这样做!@aix是正确的,这个答案引入了一个安全漏洞,攻击者可以使用CSRF请求强制登录攻击者控制的凭据。攻击者随后可以使用相同的账户查看用户在该网站上的活动。请参见http://en.wikipedia.org/wiki/Cross-site_request_forgery#Forging_login_requests和http://www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf。请考虑撤回或编辑此答案,因为它是非常危险的建议。 - ShadowChaser
1
@ShadowChaser 他的评论明确表明他特别谈论的是它在ASP.NET MVC 5中的实现方式。 - Justin Skiles
6
如果我们不应该在登录页面使用ASP.NET防伪标记,并且需要CSRF保护,那么有没有好的替代方案?我的意思是,你有没有推荐的好库或类似工具? - nmit026
显示剩余10条评论

7
我已经在这里撰写了完整的解决方案: https://richardcooke.info/en/2014/keep-users-signed-in-after-asp-net-deploy/ 以下是您需要在Controller中从GET方法调用的必要代码:
private void SetANewRequestVerificationTokenManuallyInCookieAndOnTheForm()
{
    if (Response == null)
        return;

    string cookieToken, formToken;
    AntiForgery.GetTokens(null, out cookieToken, out formToken); 
    SetCookie("__RequestVerificationToken", cookieToken);
    ViewBag.FormToken = formToken;
}

private void SetCookie(string name, string value)
{
   if (Response.Cookies.AllKeys.Contains(name))
       Response.Cookies[name].Value = value;
   else
       Response.Cookies.Add(new HttpCookie(name, value));
}

将以下代码放入您的视图中,以替代Html.AntiForgeryToken():

@if (ViewBag.FormToken != null)
{
    <text><input name="__RequestVerificationToken" type="hidden" value="@ViewBag.FormToken" /></text>
}
else
{
    <text>@Html.AntiForgeryToken()</text>
}

谢谢,这个解决方案对我解决Qualys 150129不足的会话保护/再生漏洞非常有效。 - Ege Bayrak
更新链接:https://richardcooke.info/en/2014/keep-users-signed-in-after-asp-net-deploy/ - ManojAnavatti
谢谢@Manoj。我将我的博客从WordPress切换到Hexo,并已经在我的回答中更新了链接。 - Richard
谢谢@Richard。您的解决方案帮助我解决了“登录后会话标识符未更改”的安全问题。 - ManojAnavatti

5

我的解决方案是:

如果再次进入登录页面,重新加载页面。 这将确保反跨站点请求伪造令牌的新加载

一切都完成了


1
我正在使用相同的方法。为此,我确保缓存标头设置正确:(Cache-Control=no-cache, no-store, must-revalidate),(Expires=-1)。考虑到防伪令牌根据用户上下文是“动态”的,除了在所有应用程序页面上设置no-cache之外,没有太多选择(叹气),对吧?我的意思是,用户可以登录,然后潜在地点击回到他们之前所在的任意应用程序页面...如果该页面被缓存,并且他们试图从中发布,则会出现错误。在我看来,整个Web应用程序的no-cache是唯一的解决方案:( - sammy34
注意:被点赞的答案“不要实现伪造令牌”并没有涵盖用户登录后导航回到其他(非登录)应用程序页面,其中伪造令牌是有意义的情况。 - sammy34

1

与其他帖子提到的检查User.Identity.IsAuthenticated不同,我使用了自定义属性来处理异常,并在它是HttpAntiForgeryToken时将用户重定向到主页。

我认为这避免了使用其他方法可能存在的任何安全问题,并且[ValidateAntiForgeryToken]应始终用于POST方法。

public override void OnException(ExceptionContext filterContext)
    {
        var controllerName = (string)filterContext.RouteData.Values["controller"];
        var actionName = (string)filterContext.RouteData.Values["action"];
        var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
        if (filterContext.Exception is HttpAntiForgeryException)
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary
                {
                    { "action", "Index" },
                    { "controller", "Home" }
                });

            filterContext.ExceptionHandled = true;
        }
}

受保护的重写子程序 OnException(filterContext As ExceptionContext) 如果 filterContext.Exception 是 HttpAntiForgeryException 类型 Then Dim result = New RouteValueDictionary() filterContext.Result = RedirectToAction("LogOn", "Account") filterContext.ExceptionHandled = True End If End Sub - AHMED RABEE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接