Как защитить от CSRF по умолчанию в ASP.NET MVC 4? - PullRequest
21 голосов
/ 01 апреля 2012

Есть ли способ гарантировать, что формы ASP.NET MVC 4 по умолчанию защищены от CSRF?

Например, есть ли способ автоматически применить AntiForgeryToken ко всем формам ви представления, и действия контроллера?

Справочная информация по этому вопросу: Предотвращение подделки межсайтовых запросов (CSRF) с помощью вспомогательного средства AntiForgeryToken () ASP.NET MVC и Анатомия перекрестного запроса.запрос сайта подделка атаки .

Ответы [ 4 ]

22 голосов
/ 10 января 2013

Чтобы добавить к отличному ответу osoviejo, приведенные ниже инструкции из моего недавнего сообщения в блоге о CSRF объединяют его работу с информацией в блоге Фила в одном исчерпывающем ответе.

ASP.NET / MVC предоставляет механизм для этого: вы можете добавить в коллекцию фильтров глобальный объект FilterProviders.Это позволяет вам ориентироваться на некоторые контроллеры, а не на другие, добавляя необходимую функцию безопасности.

Во-первых, нам нужно реализовать IFilterProvider.Ниже вы найдете класс поставщика условных фильтров Фила Хаака .Начните с добавления этого класса в ваш проект.

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);
    }
}

Затем добавьте в 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);

Если вы реализуете два фрагмента кода выше, ваше MVC-приложение должно требовать AntiForgeryToken для каждого POST для сайта.Вы можете попробовать его на примере сайта CSRF Фила Хаака - после защиты атака CSRF выдаст System.Web.Mvc.HttpAntiForgeryException без добавления аннотации [ValidateAntiForgeryToken].Это исключает целый ряд уязвимостей, связанных с «забывчивым программистом».

11 голосов
/ 16 июля 2012

Вы можете использовать поставщика фильтров с условием, что фильтр ValidateAntiForgeryTokenAttribute () должен применяться всякий раз, когда HttpContext.Request.HttpMethod == "POST".

Я по существу следовал универсальному подходу , описанному Филом Хааком , и добавил соответствующее условие:

// Ensure all POST actions are automatically decorated with the ValidateAntiForgeryTokenAttribute.
( c, a ) => string.Equals( c.HttpContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase ) ?
 new ValidateAntiForgeryTokenAttribute() : null
2 голосов
/ 02 апреля 2012

Я использовал FXCop для написания двух правил анализа кода, одно из которых требует применения атрибута HttpMethod ко всем действиям контроллера, а второе, требующее любого действия, имеющего атрибут HttpPost, также должен иметь атрибут RequAntiForgeryToken.

Это хорошо сработало для нас. Правила не особо сложны для написания

1 голос
/ 01 апреля 2012

Один из способов сделать это - изменить шаблоны T4 в ASP.NET MVC, которые создают формы, чтобы они автоматически вставляли этот код:

<% using(Html.Form("UserProfile", "SubmitUpdate")) { %>
    <%= Html.AntiForgeryToken() %>
    <!-- rest of form goes here -->
<% } %>

И, конечно, вам нужен соответствующий атрибутна методе контроллера:

[ValidateAntiForgeryToken]
public ViewResult SubmitUpdate()
{
    // ... etc
}

Это не так сложно дооснастить приложение таким образом, если оно необычно велико.Последнее приложение, которое я написал в MVC, вероятно, заняло бы у меня пару часов до модернизации.

...