如何在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中写的最后一个应用程序可能需要花费几个小时才能进行改造。