Подтвердить что ты не робот

Как защитить CSRF по умолчанию в ASP.NET MVC 4?

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

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

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

4b9b3361

Ответ 1

Чтобы добавить к 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);
    }
}

Затем добавьте код в 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 на сайт. Вы можете попробовать его на сайте Phil Haack веб-сайт примера CSRF - после защиты CSRF-атака будет бросать System.Web.Mvc.HttpAntiForgeryException без добавления [ValidateAntiForgeryToken] аннотация. Это исключает всю уязвимость, связанную с "забывчивым программистом".

Ответ 2

Вы можете использовать поставщика фильтра с условием, чтобы фильтр 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

Ответ 3

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

Это сработало для нас. Правилам не особо сложно написать

Ответ 4

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

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

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

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

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