繁体   English   中英

ASP.NET MVC3 AntiForgeryToken

[英]ASP.NET MVC3 AntiForgeryToken

这里我有简单的MVC3应用程序和两个表单帖子。 为了保护CSRF攻击,我按照这里的指导使用了两种形式的antiforgerytoken html助手。

这是我的两个模型:

public class User
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}


public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
}

这是我的homeController.cs:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Index(User user)
    {
        if (ModelState.IsValid)
            return RedirectToAction("About");

        return View();
    }

    public ActionResult About()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult About(Employee employee)
    {
        if (ModelState.IsValid)
            return RedirectToAction("PageA");

        return View();
    }
}

这是我的Inex.cshtml:

@model MvcAntiforgeryToken.Models.User

@using (Html.BeginForm()) {

@Html.AntiForgeryToken()
<div>
    <fieldset>
        <legend>User Information</legend>

        <div class="editor-label">
            @Html.LabelFor(m => m.FirstName)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.FirstName)
            @Html.ValidationMessageFor(m => m.FirstName)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.LastName)
        </div>
        <div class="editor-field">
            @Html.PasswordFor(m => m.LastName)
            @Html.ValidationMessageFor(m => m.LastName)
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
</div>

}

这是我的About.cshtml:

@model MvcAntiforgeryToken.Models.Employee

@using (Html.BeginForm()) {

@Html.AntiForgeryToken()
<div>
    <fieldset>
        <legend>Employee Information</legend>

        <div class="editor-label">
            @Html.LabelFor(m => m.Id)
        </div>
        <div class="editor-field">
            @Html.TextBoxFor(m => m.Id)
            @Html.ValidationMessageFor(m => m.Id)
        </div>

        <div class="editor-label">
            @Html.LabelFor(m => m.Name)
        </div>
        <div class="editor-field">
            @Html.PasswordFor(m => m.Name)
            @Html.ValidationMessageFor(m => m.Name)
        </div>
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
</div>

}

发布主页/索引:

当用户访问主页/索引,应用程序创建与值“RequestVerificationToken_Lw”曲奇“PG2 / E00Q2DngYxs98f92x9qqrIvrh6zCT / + GGte67NFZLazKFlz ++ QqMSHpkZ08Qum9vsBCtq7O7MSzCawJkEa2 / hdjrWoAcHlDWxxYRWKXm + OxPbqlRs609zam4fK7hReGEX3zf8YR4ltH3oYf4AZgt2mZV31ihRGShiZ7Oy9k =”

并跟随隐藏的表单输入

<input name="__RequestVerificationToken" type="hidden" value="B1KKzYEFEdINnuhy53MqqxHCHELPUd5pX3vRqYWz1+pkhBA6YGFvSVtXgSURkAn3yNwee3nrqDCMXB8MB0SWiUU3GuHnhH7+Qc1IQebJHoFJZR2CPXNOmUzINXbBWKZz+35pQQQXdiKptR3raLSoElfQi18ZC4Pr7xNREGIOM2A=" /> 

发布主页/关于:

当用户访问首页/公司,应用程序创建的“RequestVerificationToken_Lw”与价值“PG2 / E00Q2DngYxs98f92x9qqrIvrh6zCT / + GGte67NFZLazKFlz ++ QqMSHpkZ08Qum9vsBCtq7O7MSzCawJkEa2 / hdjrWoAcHlDWxxYRWKXm + OxPbqlRs609zam4fK7hReGEX3zf8YR4ltH3oYf4AZgt2mZV31ihRGShiZ7Oy9k =”饼干

并按照表格输入

<input name="__RequestVerificationToken" type="hidden" value="UOCMATdy93A0230aBmRPv5F0xpJlI2urE5sJ4nxsTSWrsi9/xM5qhrxQ4I2vWIjvVrhkW8gSgmGFp7c4XPQUQG5myMGipTAr2/mi5od+Sz6IcfrF2FxwjfWMslt96BcMG6b9BjaGbgnClQOVTkjfHEMIptOYUCTSbVK61dWp5qI=" /> 

这是我的问题:

  1. 为什么两个表单中的“ RequestVerificationToken_Lw ”cookie值相同? 不应该为每个表格帖子重新创建它吗?

  2. 为什么“ RequestVerificationToken_Lw ”cookie值与“__RequestVerificationToken”隐藏输入值不同?

非常感谢您的回复!

CSRF攻击媒介的想法是这样的:我在我的网站https://fake-domain-that-looks-like-a-bank.com上提出了一个恶意形式。 我从你的网站上获取了HTML和CSS,所以它看起来完全一样。 我有一个有效的证书和所有标志铃声和口哨声。 现在我欺骗用户访问我的网站。

用户看到通常的形式并做了一些事情。 但是,我替换了一些输入,所以它们无处可去,我添加了一些隐藏的字段,所以我控制用户做什么(不由自主),比如用op=delete替换'op=modify 他的所有行为都由他的(有效)身份验证cookie支持。

现在反伪造令牌可以保护用户,因为作为攻击者,我无法添加一个与他的cookie匹配的有效隐藏字段到我的表单。 如果我能以某种方式阅读他的饼干,我可以简单地窃取认证令牌,这将更容易。

在MVC中,防伪令牌绑定到登录用户的名称。 如果您正在使用FormsAuthentication并更改用户名的结构,则所有具有现有cookie的用户都将遇到麻烦。 作为旁注:常见问题是维护两个帐户的用户遇到AntiForgeryTokenExceptions ,如果它是有效的使用方案,您可能希望处理它。

解决实际问题:

为什么cookie不会改变

如果cookie值随每个请求而改变,则多标签浏览将是一个问题。

为什么cookie和表单值不同

MVC的cookie具有内部结构,因此它们的序列化版本看起来不同。 内部的实际安全令牌应该是相同的。 序列化程序根据存在的信息(用户身份名称等)存储不同的信息。 还有一个版本字节,指示这是否是会话cookie等。

坚韧不拔的细节

如果您想了解更多信息,我建议您通过http://aspnetwebstack.codeplex.com/克隆源代码,并查看System.Web.WebPages\\Helpers\\AntiXsrf\\TokenValidator.cs以及其他文件。 在任何情况下都有源代码是非常有帮助的。

我没有明确的想法,但我认为“RequestVerificationToken_Lw”应该有一个值,它将通过一个会话。 它不会为每个表单创建新值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM