【问题标题】:Why does ValidateAntiForgeryTokenAttribute allow anonymous tokens?为什么 ValidateAntiForgeryTokenAttribute 允许匿名令牌?
【发布时间】:2014-12-07 19:23:46
【问题描述】:

在 ASP.NET MVC 中,ValidateAntiForgeryTokenAttribute 调用的验证逻辑允许匿名防伪令牌,即没有任何用户特定信息(如 IIdentity.Name 或 ClaimUid)的令牌。

因此,如果未使用声明并且在登录后未设置 HttpContext.User(很常见),系统的恶意用户可以使用恶意用户自己合法获得的反伪造令牌。

这似乎不可取。为什么允许匿名令牌?

【问题讨论】:

  • 我已经回答了你的问题,除了一部分 - 你是什么意思 HttpContext.User 在登录后没有设置?发生这种情况的唯一方法是登录失败或者您在处理 POSTed 登录表单后没有执行重定向。
  • @Tommy 如果您没有显式设置 HttpContext.User(就像 FormsAuthentication 通过读取登录时设置的 cookie 所做的那样),则 HttpContext.User 对所有登录用户都是相同的,因此“匿名”。
  • 我从未在我们用 MVC 制作的任何应用程序中看到过这种行为。一旦我们设置了 Auth Cookie(在 Identity 或 FormsAuthentication 中)——我们永远不必“手动”设置 cookie 或 HttpContext.User。我很好奇您的身份验证是如何设置的。无论哪种方式,为了解决您的问题,AntiForgery 令牌不用于授权资源,仅用于验证来自您的服务器的请求和用户响应
  • 如果您不使用 FormsAuthentication 或其他身份提供者,您必须自己设置 HttpContext.User - 否则对于所有登录用户来说都是平等的。但是如果你没有使用 HttpContext.User,很容易忘记这一点。
  • Gotcha - 我以为您正在使用其中之一,但仍然必须手动控制它。我的误解。

标签: .net asp.net-mvc csrf


【解决方案1】:

MVC 中的反 CSRF 系统允许匿名用户,因为它需要保护登录页面,并且根据定义,您在登录之前是匿名的。特别是它正在尝试的攻击防御是Login CSRF

由于反 CSRF 令牌被拆分为 HTTP cookie 和隐藏的 元素,攻击者是否能够成功登录 CSRF 取决于他所在的位置。当然——你可以说服我的浏览器提交一个包含 your 令牌的

,但我的浏览器会将 my cookie 连同请求一起提交给服务器。 cookie 和表单标记不仅仅编码字符串“anonymous”:它们还包含一个随机标识符,将两者联系在一起。在这种情况下,您仍然无法对我发起登录 CSRF 攻击,因为您不知道我的 cookie 中包含的随机标识符。

如果攻击者与目标网站共享一个域(例如,attacker.shareddomain.com 和 bank.shareddomain.com),那么攻击者可以为 *.shareddomain.com 设置一个 cookie,并用一个覆盖受害者的 cookie他自己选择的。这将允许发生 CSRF 攻击。您需要另一种机制(如 2FA 或 HTML5 本地存储)来防止共享子域场景中的 CSRF 攻击。

【讨论】:

  • 啊,我不知道登录 CSRF。谢谢!除了您描述的子域攻击之外,还有需要无 cookie 解决方案的 Ajax 案例。例如这里描述的:asp.net/web-api/overview/security/….
【解决方案2】:

它不允许匿名令牌!

由于某些原因(我自己也不知道!),令牌同时写入 HTTP 标头和 cookie 中。但是,只会检查用 COOKIE 写入的令牌。换句话说:

1) 如果您阻止发送 cookie 并且您的 ActionMethod 具有 [ValidateAntiForgeryToken()] 属性,您将收到以下异常:

The required anti-forgery form field __requestverificationtoken is not present.

2) 可以更改写在 Http Header 中的令牌...! - 不会发生任何错误...!

AntiForgeryToken的主要用途:

这是一种确保接收到服务器的表单数据是通过服务器创建并发送给客户端的表单提交的解决方案(不是来自伪造的表单!)。

所以,如果两个合法用户更改了他们的 cookie 并提交了表单,服务器将接受他们两个!因为服务器创建并发送了这两种形式!(实际上,两种令牌......!)

阅读更多关于AntiForgeryTokenhere

【讨论】:

  • 是的,允许匿名令牌,即没有用户或声明信息的令牌。我的问题不在于令牌的使用。
  • @AndreasHallberg - 但是你的答案隐藏在令牌的使用中:It's a solution for ensuring that the form data received to the server, is submitted through the form which is created and sent to the client by the server(Not from a forged form!) 这就是为什么它的行为就像你说的那样......
【解决方案3】:

AntiForgery 令牌用于防止 CSRF(跨站点请求),它们不用于确保返回的数据来自授权用户,这就是 IdentityFormsAuthentication 库的用途(认证和授权)。

AntiForgery 令牌使用一些已知信息来生成包含在 POST 响应中的随机文本字符串。其中一项信息是用户名。不需要身份验证(匿名站点搜索、匿名调查等)就可以有一个 POSTed 表单。这就是为什么必须允许AntiForgery 令牌与用户名anonymous 一起使用。

鉴于 AntiForgery 令牌的作用只是防止 CSRF 攻击(从完全不同的网站向您的服务器发送邮件),那么在 AntiForgery 令牌中使用匿名用户名不应该是一个问题。当有人回帖到您的服务器并且他们必须登录才能执行该操作时,您应该使用[Authorize] 属性来捕捉它。该属性连同 AntiForgery 令牌将确保 a) 授权用户已提出此请求,并且 b) 他们是从您的网站而不是从您的网站外部提出的。

【讨论】:

  • 我的观点是匿名 AntiForgery 令牌不会阻止 CSRF,因为如果攻击者可以访问与受害者相同的 Web 应用程序,他可以在伪造请求中使用他的令牌。 Web 应用程序无法区分攻击者的令牌和受害者的令牌。
  • @AndreasHallberg - 这不是 CSRF。 CSRF 是如果有人可以从www.badurl.com 发帖到您的网站www.myurl.com。同样,这些用于验证或授权请求。您正在描述更多关于 Session hijacking 的问题,这就是为什么如果您需要将请求与特定用户相关联,您应该使用 FormsAuthentication cookie/token 而不是 AntiForgery 本身。
  • 是的,它是 CSRF。我的问题是,我描述了一个常规的 CSRF 攻击,该攻击在伪造请求中嵌入了(攻击者的)匿名防伪令牌。应用程序无法将攻击者的令牌与用户在真实请求中提供的令牌区分开来。
【解决方案4】:

AntiForgery 令牌包含 username 并且对于 anonymous 用户 username 将为空。用户登录并下次使用生成的令牌后,令牌验证将失败,因为初始令牌中包含的空用户名与当前已验证的用户名不同。了解更多信息read this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多