反伪造 - 更好地理解它的运作方式

时间:2016-07-24 18:22:57

标签: html asp.net-mvc asp.net-core csrf-protection antiforgerytoken

我正在学习如何保护网站免受未经授权的访问,我遇到了防伪。这是我的想法(以及我的问题)。如果我错了,请纠正我。

通过将@Html.AntiForgeryToken()插入网页上的Form,处理ASP.NET MVC应用程序中的防伪(可能还有很多其他方法,但这个方法很常见) 。

此标记随后在用户尝试POST数据发送到系统后使用,如果我们使用IActionResult属性装饰我们的JsonResult[ValidateAntiForgeryToken]方法,则会检查密钥是否与预期结果匹配。以下是装饰的含义示例:

    [Route("")]
    [HttpPost("")]
    [ValidateAntiForgeryToken]
    public JsonResult UpdateRecords([FromBody]CustomRequest request)
    {
        if (ModelState.IsValid)
        {
            //...do some logic here
        }
    }

网络用户使用防伪密钥的原因是,我们不希望允许未经授权访问我们的业务对象(如数据库)。问题是,如果网站使用cookie验证,存储到本地缓存,黑客可以轻松检索此存储的值,并在将数据发布到我们的网站时使用它。因此,我们正在实施另一个级别的保护,即通过在网页上插入一个特殊的(唯一的)密钥,在发布数据时进行检查。如果密钥不匹配,则整个发布过程失败。

这是我不明白的事情。假设我们已经在我们的网页上以超简单的形式实现了防伪,如下所示:

    <form method="post" ng-submit="addItem()" id="main-form">
        @Html.AntiForgeryToken()
        <input placeholder="Add New Item" ng-model="newItem" id="new-item" />
    </form>

我知道它什么都不做,但让我们想象一下,通过点击input按钮,用户会尝试将一些数据发布到数据库中。如果我们检查网页,我们会突然看到,这就是HTML生成代码的样子:

    <form class="ng-pristine ng-valid" method="post" ng-submit="addItem()" id="main-form">
        <input name="__RequestVerificationToken" value="CfDJ8Ig8dRjRrw9FjKYv6kYaxVu7APOddjpVxQ3ZxGaamjVzV03eQEG7tgRe5q2uXJkKkbUf4RqzRCtJ1DGMK5C-ymroTBe_J9XQ-...(more text here )" type="hidden">
        <input class="ng-pristine ng-valid ng-touched" placeholder="Add New Item" ng-model="newItem" id="new-item">
    </form>

现在,我(和潜在的黑客)可以看到的是我们刚才谈到的特殊防伪密钥。为什么使用该网站的任何人都可以看到这个密钥?我从中理解的是,我们基本上是为黑客提供代码,现在他可以在发布到数据库时轻松使用它来验证自己;或者我错了吗?

此刻我很困惑,因此有关此事的任何帮助/信息或建议都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

令牌可以防止人们伪造表单请求。每次需要时它也会重新生成 - 至少是每个用户,也可能是每个请求(我不确定最后一点)。这意味着攻击者无法复制自己的令牌,也无法将其复制;他们必须从用户的页面中获取它,如果他们可以这样做,那么他们可能有足够的信息来绕过令牌。

攻击者可以在另一个网站上创建一个带有某些值的表单,并将其指向您网站上的某个页面。如果管理员提交此表单(例如,无意中通过javascript),那么他们实际上只是使用他们的权限和攻击者指定的值执行该操作。这很糟糕,有足够的知识可以诱骗某人删除帐户,发布淫秽内容等等。