如何在ASP.NET MVC 4中默认防止CSRF?
有没有办法确保默认情况下ASP.NET MVC 4表单受CSRF保护?
例如,有没有办法让AntiForgeryToken 自动应用于视图和控制器操作中的所有表单?
关于这个问题的背景: 使用ASP.NET MVC的AntiForgeryToken()帮助程序和跨站点请求伪造攻击剖析来 防止跨站点请求伪造(CSRF) 。
为了增加osoviejo的优秀答案,我在最近关于CSRF的博客文章中的说明将他的工作与Phil博客中的信息放在一个综合答案中。
ASP.NET / MVC为此提供了一种机制:您可以添加到全局FilterProviders
对象上的filter集合。 这允许您针对某些控制器而不是其他控制器,添加所需的安全function。
首先,我们需要实现一个IFilterProvider。 下面,您可以找到Phil Haack的条件filter提供程序类。 首先将此类添加到项目中。
public class ConditionalFilterProvider : IFilterProvider { private readonly IEnumerable> _conditions; public ConditionalFilterProvider( IEnumerable> conditions) { _conditions = conditions; } public IEnumerable GetFilters( ControllerContext controllerContext, ActionDescriptor actionDescriptor) { return from condition in _conditions select condition(controllerContext, actionDescriptor) into filter where filter != null select new Filter(filter, FilterScope.Global, null); } }
然后,将代码添加到Application_Start,将新的ConditionalFilterProvider
添加到全局FilterProviders集合,以确保所有POST控制器方法都需要AntiForgeryToken。
IEnumerable> conditions = new Func[] { // Ensure all POST actions are automatically // decorated with the ValidateAntiForgeryTokenAttribute. ( c, a ) => string.Equals( c.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase ) ? new ValidateAntiForgeryTokenAttribute() : null }; var provider = new ConditionalFilterProvider(conditions); // This line adds the filter we created above FilterProviders.Providers.Add(provider);
如果您实现上面的两段代码,您的MVC应用程序应该为站点的每个 POST都要求AntiForgeryToken。 您可以在Phil Haack的CSRF示例网站上进行尝试 – 一旦受到保护,CSRF攻击将抛出System.Web.Mvc.HttpAntiForgeryException
而无需添加[ValidateAntiForgeryToken]
注释。 这排除了一大堆“健忘的程序员”相关漏洞。
您可以使用filter提供程序,条件是每当HttpContext.Request.HttpMethod ==“POST”时应用filterValidateAntiForgeryTokenAttribute()。
我基本上遵循Phil Haack描述的通用方法,并添加了适当的条件:
// Ensure all POST actions are automatically decorated with the ValidateAntiForgeryTokenAttribute. ( c, a ) => string.Equals( c.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase ) ? new ValidateAntiForgeryTokenAttribute() : null
我已经使用FXCop编写了两个代码分析规则,其中一个需要将HttpMethod属性应用于所有控制器操作,另一个需要具有HttpPost属性的任何操作也必须具有RequiresAntiForgeryToken属性。
这对我们很有用。 这些规则并不是特别难以写
一种方法是修改ASP.NET MVC中创建表单的T4模板,让它们自动插入此代码:
<% using(Html.Form("UserProfile", "SubmitUpdate")) { %> <%= Html.AntiForgeryToken() %> <% } %>
当然,您需要控制器方法的相应属性:
[ValidateAntiForgeryToken] public ViewResult SubmitUpdate() { // ... etc }
以这种方式改造应用程序并不困难,除非它非常大。 我在MVC中写的最后一个应用程序可能需要花费几个小时才能进行改造。