根据我的研究,防止这种情况的正确方法是为每个返回表单的 GET 请求设置一个 NONCE,然后检查 POST 请求上的 NONCE。但是,仍然有人可以编写脚本来获取我的表单以及 NONCE,然后将其与 NONCE 一起发布。
由于这是一个广为人知的漏洞,浏览器不应该通过不允许跨域 ajax 调用来解决这个问题吗?如果没有,ASP.NET MVC 4 是否已经有内置机制来防止这种情况?
3 回答
这些随机数用于防止跨站点请求伪造。不需要跨域 ajax 调用来实现这一点 - 浏览器确实有针对这些的保护。CSRF 是一个漏洞,因为当浏览器调用您的站点时,它会发送您站点的会话信息,而不管告诉浏览器进行调用的页面是什么。通过在 evilsite.com 上包含一个指向您 site.com 上的页面的 img 标签,可以告诉浏览器向您的 site.com 发出 get 请求。如果在 yoursite.com 处理该获取请求时您验证了 nonce,则 evilsite.com 的驱动器将无法知道 nonce。类似的事情也可以用于发布请求。
这个页面似乎有一些关于如何在 ASP.NEt MVC 中缓解这种情况的信息: http ://www.asp.net/mvc/overview/security/xsrfcsrf-prevention-in-aspnet-mvc-and-web-pages
干杯,斯特凡
是的,有一个内置机制。HtmlHelper.AntiForgeryToken,可用于帮助保护您的应用程序免受跨站点请求伪造。要使用此功能,请从表单调用 AntiForgeryToken 方法,并将ValidateAntiForgeryTokenAttribute特性添加到要保护的操作方法中。
CSHTML 文件:
@Html.AntiForgeryToken()
控制器:
[ValidateAntiForgeryToken]
public ActionResult Edit(User updatedUser)
您会注意到令牌涉及两个安全措施——一个表单字段和一个 cookie:
要生成反 XSRF 令牌,请从 MVC 视图调用 @Html.AntiForgeryToken() 方法或从 Razor 页面调用 @AntiForgery.GetHtml()。然后运行时将执行以下步骤:
如果当前 HTTP 请求已经包含一个反 XSRF 会话令牌(反 XSRF cookie __RequestVerificationToken),则从中提取安全令牌。如果 HTTP 请求不包含 anti-XSRF 会话令牌或安全令牌提取失败,则会生成一个新的随机 anti-XSRF 令牌。
使用上述步骤 (1) 中的安全令牌和当前登录用户的身份生成反 XSRF 字段令牌。
如果在步骤 (1) 中生成了一个新的反 XSRF 令牌,则会创建一个新的会话令牌来包含它,并将其添加到出站 HTTP cookie 集合中。步骤 (2) 中的字段标记将被包装在一个元素中,此 HTML 标记将是 Html.AntiForgeryToken() 或 AntiForgery.GetHtml() 的返回值。
阅读:
您还应该看看无状态 CSRF 保护的概念。有两种标准方法可以实现这一点:加密令牌模式和双重提交 Cookie 模式。加密令牌模式利用了 Rijndael 加密令牌,其中包含脚本无法读取的内置 nonce 值,并且是一种非常强大的加密结构。