ASP.NET MVC 中的 AntiForgeryToken 是不是可以防止所有 CSRF 攻击?
Posted
技术标签:
【中文标题】ASP.NET MVC 中的 AntiForgeryToken 是不是可以防止所有 CSRF 攻击?【英文标题】:Does AntiForgeryToken in ASP.NET MVC prevent against all CSRF attacks?ASP.NET MVC 中的 AntiForgeryToken 是否可以防止所有 CSRF 攻击? 【发布时间】:2010-12-20 14:59:18 【问题描述】:使用 AntiForgeryToken 要求每个请求都传递一个有效的令牌,因此带有简单脚本的恶意网页将数据发布到我的 Web 应用程序将不会成功。
但是,如果恶意脚本首先发出一些简单的 GET 请求(通过Ajax),以便在隐藏的输入字段中下载包含防伪令牌的页面,提取它并使用它来生成有效的@987654322,那该怎么办? @?
有可能吗,还是我错过了什么?
【问题讨论】:
【参考方案1】:是的,这就是你需要做的。
只要您在每个受保护的页面上生成一个新令牌,使用<%= html.AntiForgeryToken() %>
并始终确保在任何受保护的操作中检查它,使用[ValidateAntiForgeryToken]
这实现了同步器令牌模式,如 OWASP 的CSRF Prevention Cheat Sheet 中所述。
为了让脚本成功发出可接受的请求,它必须首先获取表单并读取令牌,然后发布令牌。 Same Origin Policy 将阻止浏览器允许这样做。一个站点不能向另一个站点发出 AJAX 样式的 http 请求;只对自己。如果由于某种原因可能违反同源策略,那么您将变得容易受到攻击。
注意,如果你有跨站脚本漏洞,那么攻击者可以滥用xss漏洞绕过同源策略提供的保护(因为脚本现在是从你自己的站点运行的,所以SOP成功了)。然后注入的脚本可以愉快地读取并重新提交令牌。这种通过 XSS 绕过 CSRF 保护的技术最近在一些蠕虫中很常见。基本上,如果你有 XSS,你的 CSRF 保护就是浪费时间,所以要确保你不会受到任何攻击。
另一件需要注意的是 Flash 和 Silverlight。这两种技术都不订阅同源策略,而是使用跨域策略文件来限制对远程资源的访问。如果您在自己的站点上发布跨域策略 xml 文件,Flash/Silverlight 脚本只能访问您站点上的资源。如果您确实发布了此文件,请只允许受信任的第三方服务器的白名单,并且绝不允许 *。
阅读更多关于CSRF at OWASP 另见:XSS Prevention Cheat Sheet
【讨论】:
所以除了验证令牌之外,还必须小心使用 crossdomain.xml,对吧?如果我理解正确,为不受限制的跨域请求(crossdomain.xml 中的 allow-http-request-headers-from domain="*")公开 Web 应用程序会破坏 AntiForgeryTokens 的目的,并使站点 CSRF 易受攻击? 是的。如果你在你的服务器上发布了一个 crossdomain.xml 策略文件,那么你可以在远程 Flash 电影中重新打开通过 ActionScript 进行的 CSRF 攻击。如果您发布此文件,则只将受信任的第三方列入白名单,并且永远不会 *.我会把这个添加到答案中 "一个站点不能向另一个站点发出 AJAX 样式的 http 请求;只能对它自己" 谷歌分析是如何工作的呢?我认为 Same-Origin-Policy 与无法读取/修改另一个站点的 cookie 有关。 @Marco M. Google Analytics(分析)代码在页面中嵌入了 GA 托管的图像。该图像的 URL 包含一些信息,用于识别页面和 GA 帐户以及其他一些信息。然后浏览器去 GA 请求这个图像,其余的数据是从浏览器的 HTTP 请求中收集的。未使用 XmlHttpRequest。【参考方案2】:但是如果恶意脚本首先发出一些简单的 GET 请求(通过 AJAX)以下载隐藏输入字段中包含防伪令牌的页面,提取它并使用它进行有效的 POST,该怎么办?
是的,这是真的,但是,如果它没有在浏览器中结束,这不是 CSRF 攻击。
如果它确实结束了浏览器(例如通过服务器端代码中的 HTTP 请求进行抓取),那么抓取代码将获得 CSRF 令牌会发生什么。但是,您的合法、经过身份验证的用户将在他们的机器上获得不同的令牌。因为刮板提升的令牌与发给您的用户的令牌不同,所以 POST 将失败。
如果您想阻止非浏览器脚本发布帖子,那么您需要采取另一种方法来验证它是不是人类。
【讨论】:
通过使用 AJAX 发出 GET 请求,我的意思是 GET 是由嵌入在某个页面上的恶意脚本执行的,该页面是由用户在浏览器中打开的,用户以某种方式被欺骗打开这样的页面。这样脚本将在用户的上下文中执行。所以我认为它仍然是 CSRF。 啊,我明白了。那么由于相同的原始策略,这将不起作用,除非他们在做一些棘手的事情,在这种情况下,cookie 无论如何都不会流动,所以令牌会有所不同以上是关于ASP.NET MVC 中的 AntiForgeryToken 是不是可以防止所有 CSRF 攻击?的主要内容,如果未能解决你的问题,请参考以下文章