如何在ASP.NET MVC 4中默认防止CSRF?

Fer*_*eia 22 c# csrf asp.net-mvc-4

有没有办法确保默认情况下ASP.NET MVC 4表单受CSRF保护?

例如,有没有办法让AntiForgeryToken 自动应用于视图和控制器操作中的所有表单?

关于这个问题的背景:使用ASP.NET MVC的AntiForgeryToken()帮助程序跨站点请求伪造攻击剖析来防止跨站点请求伪造(CSRF).

Kyl*_*son 23

为了增加osoviejo的优秀答案,我在最近关于CSRF的博客文章中的说明将他的工作与Phil博客中的信息放在一个综合答案中.

ASP.NET/MVC为此提供了一种机制:您可以添加到全局FilterProviders对象上的过滤器集合.这允许您针对某些控制器而不是其他控制器,添加所需的安全功能.

首先,我们需要实现一个IFilterProvider.下面,您可以找到Phil Haack的条件过滤器提供程序类.首先将此类添加到项目中.

public class ConditionalFilterProvider : IFilterProvider
{
    private readonly
      IEnumerable<Func<ControllerContext, ActionDescriptor, object>> _conditions;

    public ConditionalFilterProvider(
      IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions)
    {
        _conditions = conditions;
    }

    public IEnumerable<Filter> 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,向Application_Start添加代码,该代码向ConditionalFilterProvider全局FilterProviders集合添加一个新内容,以确保所有POST控制器方法都需要AntiForgeryToken.

IEnumerable<Func<ControllerContext, ActionDescriptor, object>> conditions = 
    new Func<ControllerContext, ActionDescriptor, object>[] {
    // 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);
Run Code Online (Sandbox Code Playgroud)

如果您实现上面的两段代码,您的MVC应用程序应该为站点的每个 POST 都要求AntiForgeryToken .你可以在Phil Haack的CSRF示例网站上试一试- 一旦受到保护,CSRF攻击就会抛出System.Web.Mvc.HttpAntiForgeryException而不必添加[ValidateAntiForgeryToken]注释.这排除了一大堆"健忘的程序员"相关漏洞.


oso*_*ejo 12

您可以使用过滤器提供程序,条件是每当HttpContext.Request.HttpMethod =="POST"时应用过滤器ValidateAntiForgeryTokenAttribute().

我基本上遵循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
Run Code Online (Sandbox Code Playgroud)