CA3147: присвоение метки ValidateAntiForgeryToken обработчикам команд

Свойство Значение
Идентификатор правила CA3147
Заголовок Присвоение метки ValidateAntiForgeryToken обработчикам команд
Категория Безопасность
Исправление является критическим или не критическим Не критическое
Включен по умолчанию в .NET 8 No

Причина

Метод действия контроллера MVC ASP.NET не помечен ValidateAntiForgeryTokenAttribute или атрибутом, указывающим HTTP-команду, например HttpGetAttribute или AcceptVerbsAttribute.

Описание правила

При разработке контроллера MVC ASP.NET следует учитывать атаки с подделкой межсайтовых запросов (CSRF). Атака с использованием подделки межсайтовых запросов позволяет отправлять вредоносные запросы от пользователя, прошедшего проверку подлинности, в контроллер MVC ASP.NET. Дополнительные сведения см. в разделе Предотвращение XSRF/CSRF на веб-страницах и в MVC ASP.NET.

Это правило проверяет, что методы действия контроллера MVC ASP.NET:

  • либо имеют ValidateAntiforgeryTokenAttribute и указывают разрешенные HTTP-команды, за исключением HTTP GET;

  • либо указывают HTTP GET как разрешенную команду.

Устранение нарушений

  • Для действий контроллера MVC ASP.NET, обрабатывающих запросы HTTP GET и не имеющих потенциально опасных побочных эффектов, добавьте HttpGetAttribute в метод.

    Если у вас есть действие контроллера MVC ASP.NET, которое обрабатывает запросы HTTP GET и имеет потенциально опасные побочные эффекты, такие как изменение конфиденциальных данных, то приложение уязвимо к атакам с подделкой межсайтовых запросов. Вам придется переконструировать приложение таким образом, чтобы конфиденциальные операции могли выполнять только запросы HTTP POST, PUT или DELETE.

  • Для действий контроллера MVC ASP.NET, обрабатывающих запросы HTTP POST, PUT или DELETE, добавьте ValidateAntiForgeryTokenAttribute и атрибуты, указывающие разрешенные HTTP-команды (AcceptVerbsAttribute, HttpPostAttribute, HttpPutAttribute или HttpDeleteAttribute). Кроме того, вам нужно вызвать метод HtmlHelper.AntiForgeryToken() из представления MVC или веб-страницы Razor. Пример см. в разделе Изучение методов Edit и представления Edit.

Когда лучше отключить предупреждения

Можно отключить вывод предупреждений для этого правила в следующих случаях:

  • Действие контроллера MVC ASP.NET не имеет вредных побочных эффектов.
  • Приложение проверяет маркер проверки подлинности другим способом.

Отключение предупреждений

Если вы просто хотите отключить одно нарушение, добавьте директивы препроцессора в исходный файл, чтобы отключить и повторно включить правило.

#pragma warning disable CA3147
// The code that's violating the rule is on this line.
#pragma warning restore CA3147

Чтобы отключить правило для файла, папки или проекта, задайте его серьезность none в файле конфигурации.

[*.{cs,vb}]
dotnet_diagnostic.CA3147.severity = none

Дополнительные сведения см. в разделе Практическое руководство. Скрытие предупреждений анализа кода.

Пример атрибута ValidateAntiForgeryToken

Нарушение:

namespace TestNamespace
{
    using System.Web.Mvc;

    public class TestController : Controller
    {
        public ActionResult TransferMoney(string toAccount, string amount)
        {
            // You don't want an attacker to specify to who and how much money to transfer.

            return null;
        }
    }
}

Решение.

using System;
using System.Xml;

namespace TestNamespace
{
    using System.Web.Mvc;

    public class TestController : Controller
    {
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult TransferMoney(string toAccount, string amount)
        {
            return null;
        }
    }
}

Пример атрибута HttpGet

Нарушение:

namespace TestNamespace
{
    using System.Web.Mvc;

    public class TestController : Controller
    {
        public ActionResult Help(int topicId)
        {
            // This Help method is an example of a read-only operation with no harmful side effects.
            return null;
        }
    }
}

Решение.

namespace TestNamespace
{
    using System.Web.Mvc;

    public class TestController : Controller
    {
        [HttpGet]
        public ActionResult Help(int topicId)
        {
            return null;
        }
    }
}