【问题标题】:Anti Forgery - better understanding how it works防伪 - 更好地了解它的工作原理
【发布时间】:2016-07-25 02:54:28
【问题描述】:

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

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

一旦用户尝试将数据POST 发送到系统后,就会使用此令牌,如果我们用[ValidateAntiForgeryToken] 属性装饰我们的IActionResultJsonResult 方法,它会检查密钥是否与预期结果匹配。这是我所说的装饰的一个例子:

    [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>

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

我现在很困惑,因此对于此事的任何帮助/信息或建议都将不胜感激。

【问题讨论】:

  • 我建议您检查 __RequestVerificationToken 的值并将其与 cookie 进行比较。您应该多次发布表单并验证隐藏输入字段__RequestVerificationToken 的值是否唯一。这意味着如果您通过 HTTP 发布数据并且有人看到流量,那么他仍然无法发布自己的请求,因为在这种情况下 AntiForgeryToken 将失败。例如,请参阅here
  • AntiForgeryToken()与授权无关。它用于防止跨站点请求伪造(CSRF)攻击。请参阅 this articlethis one 了解其用途

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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2018-05-20
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 2016-02-20
    • 2012-12-11
    • 2011-02-18
    • 2018-02-17
    相关资源
    最近更新 更多