Предотвращения межсайтовых (запросов XSRF/CSRF) атак с подделкой в ASP.NET CorePrevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core

По Стив Смит, Fiyaz Hasan, и Рик АндерсонBy Steve Smith, Fiyaz Hasan, and Rick Anderson

Подделки межсайтовых запросов (также известные как XSRF или CSRF) — это атака, от приложений веб сервере, при котором вредоносные веб-приложения может влиять на взаимодействие между клиентским браузером и веб-приложение, которому доверяет этого браузера.Cross-site request forgery (also known as XSRF or CSRF) is an attack against web-hosted apps whereby a malicious web app can influence the interaction between a client browser and a web app that trusts that browser. Эти атаки возможны, так как веб-браузеры отправляют некоторых типов маркеров проверки подлинности автоматически при каждом запросе веб-сайта.These attacks are possible because web browsers send some types of authentication tokens automatically with every request to a website. Такая форма эксплойта также называется атаки одним щелчком или «session riding» так, как атаки использует преимущества пользователь ранее проверку подлинности сеанса.This form of exploit is also known as a one-click attack or session riding because the attack takes advantage of the user's previously authenticated session.

Примером атаки CSRF:An example of a CSRF attack:

  1. Пользователь входит в www.good-banking-site.com проверки подлинности с помощью форм.A user signs into www.good-banking-site.com using forms authentication. Сервер проверяет подлинность пользователя и выдает ответ, включающий файл cookie проверки подлинности.The server authenticates the user and issues a response that includes an authentication cookie. Сайт является уязвимым для атак, так как она доверяет любой запрос, получающий объект cookie проверки подлинности.The site is vulnerable to attack because it trusts any request that it receives with a valid authentication cookie.

  2. Пользователь посещает веб, www.bad-crook-site.com.The user visits a malicious site, www.bad-crook-site.com.

    Вредоносный сайт www.bad-crook-site.com, с HTML-формой следующего вида:The malicious site, www.bad-crook-site.com, contains an HTML form similar to the following:

    <h1>Congratulations! You're a Winner!</h1>
    <form action="http://good-banking-site.com/api/account" method="post">
        <input type="hidden" name="Transaction" value="withdraw">
        <input type="hidden" name="Amount" value="1000000">
        <input type="submit" value="Click to collect your prize!">
    </form>
    

    Обратите внимание, что формы action сообщения на уязвимом сайте, а не к вредоносный сайт.Notice that the form's action posts to the vulnerable site, not to the malicious site. Это часть CSRF «cross-site».This is the "cross-site" part of CSRF.

  3. Пользователь выбирает кнопку отправки.The user selects the submit button. Браузер выполняет запрос и автоматически включает в себя файл cookie проверки подлинности для запрошенного домена www.good-banking-site.com.The browser makes the request and automatically includes the authentication cookie for the requested domain, www.good-banking-site.com.

  4. Запрос выполняется на www.good-banking-site.com сервера с контекстом проверки подлинности пользователя и могут выполнять любые действия, прошедший проверку пользователь может выполнять.The request runs on the www.good-banking-site.com server with the user's authentication context and can perform any action that an authenticated user is allowed to perform.

В дополнение к сценарии, где пользователь выбирает кнопку, чтобы отправить форму вредоносный сайт может:In addition to the scenario where the user selects the button to submit the form, the malicious site could:

  • Запустите скрипт, который автоматически отправляет форму.Run a script that automatically submits the form.
  • Отправка отправки формы в качестве AJAX-запросом.Send the form submission as an AJAX request.
  • Скрывайте форму с помощью CSS.Hide the form using CSS.

Эти альтернативные сценарии не требуется, любые действия или входные данные пользователя, отличные от изначально узле вредоносных.These alternative scenarios don't require any action or input from the user other than initially visiting the malicious site.

С помощью протокола HTTPS не предотвращает атаки CSRF.Using HTTPS doesn't prevent a CSRF attack. Можно отправить вредоносный сайт https://www.good-banking-site.com/ запроса так же легко, он может отправлять небезопасный запрос.The malicious site can send an https://www.good-banking-site.com/ request just as easily as it can send an insecure request.

Некоторые атаки направлены конечных точек, которые отвечают на запросы GET, в этом случае тег изображения может использоваться для выполнения действия.Some attacks target endpoints that respond to GET requests, in which case an image tag can be used to perform the action. Эту форму атаки характерен для веб-узлов форума, которые обеспечивают образов, но блокировка JavaScript.This form of attack is common on forum sites that permit images but block JavaScript. Приложения, которые изменяют состояние для запросов GET, где переменные или ресурсов, изменяются, уязвимы для атак злоумышленников.Apps that change state on GET requests, where variables or resources are altered, are vulnerable to malicious attacks. Запросы GET, которые изменяют состояние сделаны ненадежными. Рекомендуется никогда не изменить состояние в запрос GET.GET requests that change state are insecure. A best practice is to never change state on a GET request.

Для веб-приложений, использующих файлы cookie для проверки подлинности, так как возможны CSRF-атакам.CSRF attacks are possible against web apps that use cookies for authentication because:

  • Обозреватели сохраняют файлы Сookie, выпущенные веб-приложения.Browsers store cookies issued by a web app.
  • Хранимые файлы cookie содержат файлы cookie сеанса для прошедших проверку пользователей.Stored cookies include session cookies for authenticated users.
  • Браузеры отправляют все файлы cookie, связанную с доменом, в веб-приложение каждого запроса, независимо от того, как был создан запрос на приложение в браузере.Browsers send all of the cookies associated with a domain to the web app every request regardless of how the request to app was generated within the browser.

Тем не менее, не ограничены CSRF-атакам использования файлов cookie.However, CSRF attacks aren't limited to exploiting cookies. Например Basic и дайджест-проверки подлинности также уязвимы.For example, Basic and Digest authentication are also vulnerable. После пользователь выполняет вход с обычной или дайджест-проверки подлинности, браузер автоматически отправляет учетные данные до систему† заканчивается.After a user signs in with Basic or Digest authentication, the browser automatically sends the credentials until the session† ends.

†В этом контексте сеанса ссылается на сеанса на стороне клиента, во время которого пользователь проходит проверку подлинности.†In this context, session refers to the client-side session during which the user is authenticated. Это не имеющих отношения к сеансов на сервере или сеанс по промежуточного слоя ASP.NET Core.It's unrelated to server-side sessions or ASP.NET Core Session Middleware.

Пользователей можно защититься от уязвимостей CSRF путем принятия мер предосторожности:Users can guard against CSRF vulnerabilities by taking precautions:

  • Выйти из веб-приложения после завершения их использования.Sign off of web apps when finished using them.
  • Очистить файлы cookie браузера периодически.Clear browser cookies periodically.

Тем не менее CSRF уязвимости, по сути, проблема с веб-приложения, а не конечным пользователем.However, CSRF vulnerabilities are fundamentally a problem with the web app, not the end user.

Основы проверки подлинностиAuthentication fundamentals

Проверка подлинности на основе файлов cookie — это популярная форма проверки подлинности.Cookie-based authentication is a popular form of authentication. Систем проверки подлинности на основе маркеров растет популярность, особенно для одностраничных приложений (SPA).Token-based authentication systems are growing in popularity, especially for Single Page Applications (SPAs).

Когда пользователь проходит проверку подлинности с помощью имени пользователя и пароля, они все выданный маркер, содержащий билет проверки подлинности, который может использоваться для проверки подлинности и авторизации.When a user authenticates using their username and password, they're issued a token, containing an authentication ticket that can be used for authentication and authorization. Он хранится в файле cookie, который сопровождает запрос на каждый клиент делает.The token is stored as a cookie that accompanies every request the client makes. Проверка подлинности по промежуточного слоя выполняет формирования и проверки этот файл cookie.Generating and validating this cookie is performed by the Cookie Authentication Middleware. По промежуточного слоя сериализует участника-пользователя в зашифрованном файле cookie.The middleware serializes a user principal into an encrypted cookie. При последующих запросах по промежуточного слоя проверяет файл cookie, повторно создает основной и назначает участнику пользователя свойство HttpContext.On subsequent requests, the middleware validates the cookie, recreates the principal, and assigns the principal to the User property of HttpContext.

Проверка подлинности на основе маркеровToken-based authentication

Когда пользователь проходит проверку подлинности, они все выдачи маркера (не токен против подделки).When a user is authenticated, they're issued a token (not an antiforgery token). Маркер содержит сведения о пользователе в форме утверждений или маркера ссылки, указывающий приложение поддерживается в приложении состояние пользователя.The token contains user information in the form of claims or a reference token that points the app to user state maintained in the app. Когда пользователь пытается получить доступ к ресурсу, требующей проверки подлинности, маркер отправляется в приложение с заголовком дополнительной авторизации в виде маркера носителя.When a user attempts to access a resource requiring authentication, the token is sent to the app with an additional authorization header in form of Bearer token. В результате приложения без отслеживания состояния.This makes the app stateless. В каждый последующий запрос этот маркер передается в запросе для проверки на стороне сервера.In each subsequent request, the token is passed in the request for server-side validation. Этот токен не зашифрованных; он имеет кодировке.This token isn't encrypted; it's encoded. На сервере токен декодируется для доступа к его данным.On the server, the token is decoded to access its information. Чтобы отправить маркер при последующих запросах, сохранения токена в локальном хранилище браузера.To send the token on subsequent requests, store the token in the browser's local storage. Не стоит беспокоиться о CSRF уязвимости, если он хранится в локальном хранилище браузера.Don't be concerned about CSRF vulnerability if the token is stored in the browser's local storage. CSRF имеет значения, когда он хранится в файле cookie.CSRF is a concern when the token is stored in a cookie.

Несколько приложений, размещенных в одном доменеMultiple apps hosted at one domain

Общими средами размещения уязвимы для захвата сеанса входа CSRF и других атак.Shared hosting environments are vulnerable to session hijacking, login CSRF, and other attacks.

Несмотря на то что example1.contoso.net и example2.contoso.net находятся на разных узлах, есть неявные доверительные отношения между узлами в группе *.contoso.net домена.Although example1.contoso.net and example2.contoso.net are different hosts, there's an implicit trust relationship between hosts under the *.contoso.net domain. Неявные доверительные отношения с этой позволяет потенциально небезопасных узлам влиять на друг друга файлы cookie (политики одного источника, определяющие запросов AJAX не иметь отношения к файлы cookie HTTP).This implicit trust relationship allows potentially untrusted hosts to affect each other's cookies (the same-origin policies that govern AJAX requests don't necessarily apply to HTTP cookies).

Благодаря использованию доменов можно предотвратить атак, использующих доверенных файлов cookie в приложениях, размещенных на том же домене.Attacks that exploit trusted cookies between apps hosted on the same domain can be prevented by not sharing domains. При каждой приложение размещено на своем собственном домене, отсутствует отношение доверия неявное куки-файл для использования.When each app is hosted on its own domain, there is no implicit cookie trust relationship to exploit.

Сложные конфигурации ASP.NET CoreASP.NET Core antiforgery configuration

Предупреждение

ASP.NET Core реализует против подделки с помощью защиты данных в ASP.NET Core.ASP.NET Core implements antiforgery using ASP.NET Core Data Protection. В стеке защиты данных должен быть настроен для работы в ферме серверов.The data protection stack must be configured to work in a server farm. См. в разделе Настройка защиты данных Дополнительные сведения.See Configuring data protection for more information.

В ASP.NET Core 2.0 или более поздней версии FormTagHelper внедряет против подделки токенов в элементы HTML-формы.In ASP.NET Core 2.0 or later, the FormTagHelper injects antiforgery tokens into HTML form elements. Следующая разметка в файле Razor автоматически создает против подделки токены:The following markup in a Razor file automatically generates antiforgery tokens:

<form method="post">
    ...
</form>

Аналогичным образом IHtmlHelper.BeginForm создает против подделки токенов по умолчанию, если метод формы не GET.Similarly, IHtmlHelper.BeginForm generates antiforgery tokens by default if the form's method isn't GET.

Происходит автоматическое создание против подделки токенов для элементы HTML-формы при <form> тег содержит method="post" атрибут и одно из следующих условий:The automatic generation of antiforgery tokens for HTML form elements happens when the <form> tag contains the method="post" attribute and either of the following are true:

  • Атрибут действия пуст (action="").The action attribute is empty (action="").
  • Не указан атрибут действия (<form method="post">).The action attribute isn't supplied (<form method="post">).

Можно отключить автоматическое создание против подделки маркеры для элементы HTML-формы:Automatic generation of antiforgery tokens for HTML form elements can be disabled:

  • Явно отключить против подделки маркеры с asp-antiforgery атрибут:Explicitly disable antiforgery tokens with the asp-antiforgery attribute:

    <form method="post" asp-antiforgery="false">
        ...
    </form>
    
  • Элемент формы является согласились горизонтального вспомогательных функций тегов с помощью вспомогательной функции тега ! символ отказаться:The form element is opted-out of Tag Helpers by using the Tag Helper ! opt-out symbol:

    <!form method="post">
        ...
    </!form>
    
  • Удалить FormTagHelper из представления.Remove the FormTagHelper from the view. FormTagHelper Можно удалить из представления, добавив следующую директиву в представление Razor:The FormTagHelper can be removed from a view by adding the following directive to the Razor view:

    @removeTagHelper Microsoft.AspNetCore.Mvc.TagHelpers.FormTagHelper, Microsoft.AspNetCore.Mvc.TagHelpers
    

Примечание

Razor Pages автоматически защищаются от XSRF/CSRF.Razor Pages are automatically protected from XSRF/CSRF. Дополнительные сведения см. в разделе XSRF/CSRF и Razor Pages.For more information, see XSRF/CSRF and Razor Pages.

Для защиты от атак CSRF наиболее распространенным подходом является использование шаблона токена синхронизатор (STP).The most common approach to defending against CSRF attacks is to use the Synchronizer Token Pattern (STP). STP используется в том случае, когда пользователь запрашивает страницу с данными формы:STP is used when the user requests a page with form data:

  1. Сервер отправляет токен, связанный с удостоверением текущего пользователя на клиент.The server sends a token associated with the current user's identity to the client.
  2. Клиент отправляет обратно токен на сервер для проверки подлинности.The client sends back the token to the server for verification.
  3. Если сервер получает маркер, который не соответствует удостоверение пользователя, прошедшего проверку подлинности, запрос отклоняется.If the server receives a token that doesn't match the authenticated user's identity, the request is rejected.

Токен должно быть уникальным и непредсказуемым.The token is unique and unpredictable. Маркер можно использовать также для обеспечения правильной последовательности из ряда запросов (например, обеспечьте последовательности запроса: страницы 1 – странице 2 – странице 3).The token can also be used to ensure proper sequencing of a series of requests (for example, ensuring the request sequence of: page 1 – page 2 – page 3). Все формы в ASP.NET Core MVC и Razor Pages шаблоны создают против подделки маркеры.All of the forms in ASP.NET Core MVC and Razor Pages templates generate antiforgery tokens. В следующей паре Просмотр примеров создания против подделки маркеров:The following pair of view examples generate antiforgery tokens:

<form asp-controller="Manage" asp-action="ChangePassword" method="post">
    ...
</form>

@using (Html.BeginForm("ChangePassword", "Manage"))
{
    ...
}

Явным образом добавить токен против подделки для <form> элемент без использования вспомогательных функций тегов с помощью вспомогательного метода HTML @Html.AntiForgeryToken :Explicitly add an antiforgery token to a <form> element without using Tag Helpers with the HTML helper @Html.AntiForgeryToken:

<form action="/" method="post">
    @Html.AntiForgeryToken()
</form>

В каждом из указанных случаев ASP.NET Core добавляет скрытое поле формы следующего вида:In each of the preceding cases, ASP.NET Core adds a hidden form field similar to the following:

<input name="__RequestVerificationToken" type="hidden" value="CfDJ8NrAkS ... s2-m9Yw">

ASP.NET Core включает в себя три фильтры для работы с против подделки токенов:ASP.NET Core includes three filters for working with antiforgery tokens:

Сложные параметрыAntiforgery options

Настройка против подделки параметры в Startup.ConfigureServices:Customize antiforgery options in Startup.ConfigureServices:

services.AddAntiforgery(options => 
{
    // Set Cookie properties using CookieBuilder properties†.
    options.FormFieldName = "AntiforgeryFieldname";
    options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
    options.SuppressXFrameOptionsHeader = false;
});

†Задайте защиты от подделки Cookie свойства с помощью свойства CookieBuilder класса.†Set the antiforgery Cookie properties using the properties of the CookieBuilder class.

ПараметрOption ОписаниеDescription
Файл cookieCookie Определяет параметры, используемые для создания против подделки файлы cookie.Determines the settings used to create the antiforgery cookies.
FormFieldNameFormFieldName Имя скрытого поля формы используемые против подделки системой для подготовки к просмотру против подделки токенов в представлениях.The name of the hidden form field used by the antiforgery system to render antiforgery tokens in views.
HeaderNameHeaderName Имя заголовка, используемый системой против подделки.The name of the header used by the antiforgery system. Если null, то система рассматривает только данные формы.If null, the system considers only form data.
SuppressXFrameOptionsHeaderSuppressXFrameOptionsHeader Указывает, следует ли подавлять поколение X-Frame-Options заголовка.Specifies whether to suppress generation of the X-Frame-Options header. По умолчанию заголовок создается со значением «SAMEORIGIN».By default, the header is generated with a value of "SAMEORIGIN". По умолчанию — false.Defaults to false.
services.AddAntiforgery(options => 
{
    options.CookieDomain = "contoso.com";
    options.CookieName = "X-CSRF-TOKEN-COOKIENAME";
    options.CookiePath = "Path";
    options.FormFieldName = "AntiforgeryFieldname";
    options.HeaderName = "X-CSRF-TOKEN-HEADERNAME";
    options.RequireSsl = false;
    options.SuppressXFrameOptionsHeader = false;
});
ПараметрOption ОписаниеDescription
Файл cookieCookie Определяет параметры, используемые для создания против подделки файлы cookie.Determines the settings used to create the antiforgery cookies.
CookieDomainCookieDomain Домен cookie.The domain of the cookie. По умолчанию — null.Defaults to null. Это свойство является устаревшим и будет удален в будущей версии.This property is obsolete and will be removed in a future version. Рекомендуемой альтернативой является Cookie.Domain.The recommended alternative is Cookie.Domain.
CookieNameCookieName Имя файла cookie.The name of the cookie. Если не задано, система создает уникальное имя которого начинается с DefaultCookiePrefix (». AspNetCore.Antiforgery.»).If not set, the system generates a unique name beginning with the DefaultCookiePrefix (".AspNetCore.Antiforgery."). Это свойство является устаревшим и будет удален в будущей версии.This property is obsolete and will be removed in a future version. Рекомендуемой альтернативой является Cookie.Name.The recommended alternative is Cookie.Name.
CookiePathCookiePath Путь в файле cookie.The path set on the cookie. Это свойство является устаревшим и будет удален в будущей версии.This property is obsolete and will be removed in a future version. Рекомендуемой альтернативой является Cookie.Path.The recommended alternative is Cookie.Path.
FormFieldNameFormFieldName Имя скрытого поля формы используемые против подделки системой для подготовки к просмотру против подделки токенов в представлениях.The name of the hidden form field used by the antiforgery system to render antiforgery tokens in views.
HeaderNameHeaderName Имя заголовка, используемый системой против подделки.The name of the header used by the antiforgery system. Если null, то система рассматривает только данные формы.If null, the system considers only form data.
RequireSslRequireSsl Указывает, требуется ли HTTPS против подделки системой.Specifies whether HTTPS is required by the antiforgery system. Если true, отличных от HTTPS-запросы завершаются сбоем.If true, non-HTTPS requests fail. По умолчанию — false.Defaults to false. Это свойство является устаревшим и будет удален в будущей версии.This property is obsolete and will be removed in a future version. Рекомендуемой альтернативой является установка Cookie.SecurePolicy.The recommended alternative is to set Cookie.SecurePolicy.
SuppressXFrameOptionsHeaderSuppressXFrameOptionsHeader Указывает, следует ли подавлять поколение X-Frame-Options заголовка.Specifies whether to suppress generation of the X-Frame-Options header. По умолчанию заголовок создается со значением «SAMEORIGIN».By default, the header is generated with a value of "SAMEORIGIN". По умолчанию — false.Defaults to false.

Дополнительные сведения см. в разделе CookieAuthenticationOptions.For more information, see CookieAuthenticationOptions.

Настройка против подделки функций работы с IAntiforgeryConfigure antiforgery features with IAntiforgery

IAntiforgery предоставляет API для настройки функций против подделки.IAntiforgery provides the API to configure antiforgery features. IAntiforgery можно запросить в Configure метод Startup класса.IAntiforgery can be requested in the Configure method of the Startup class. В следующем примере используется по промежуточного слоя с домашней страницы приложения, чтобы создать токен против подделки и отправить его в ответ как файл cookie (с помощью именования по умолчанию Angular описано далее в этом разделе):The following example uses middleware from the app's home page to generate an antiforgery token and send it in the response as a cookie (using the default Angular naming convention described later in this topic):

public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
    app.Use(next => context =>
    {
        string path = context.Request.Path.Value;

        if (
            string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
            string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
        {
            // The request token can be sent as a JavaScript-readable cookie, 
            // and Angular uses it by default.
            var tokens = antiforgery.GetAndStoreTokens(context);
            context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, 
                new CookieOptions() { HttpOnly = false });
        }

        return next(context);
    });
}

Требовать проверку против подделкиRequire antiforgery validation

ValidateAntiForgeryToken является фильтром операции, которые могут применяться для отдельного действия, контроллера или глобально.ValidateAntiForgeryToken is an action filter that can be applied to an individual action, a controller, or globally. Запросы к действиям, которые имеют этот фильтр, применяемый будут заблокированы, если запрос содержит допустимый токен против подделки.Requests made to actions that have this filter applied are blocked unless the request includes a valid antiforgery token.

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
{
    ManageMessageId? message = ManageMessageId.Error;
    var user = await GetCurrentUserAsync();

    if (user != null)
    {
        var result = 
            await _userManager.RemoveLoginAsync(
                user, account.LoginProvider, account.ProviderKey);

        if (result.Succeeded)
        {
            await _signInManager.SignInAsync(user, isPersistent: false);
            message = ManageMessageId.RemoveLoginSuccess;
        }
    }

    return RedirectToAction(nameof(ManageLogins), new { Message = message });
}

ValidateAntiForgeryToken Атрибут требует маркер для запросов к методам действий, он сопровождает, включая HTTP-запросы GET.The ValidateAntiForgeryToken attribute requires a token for requests to the action methods it decorates, including HTTP GET requests. Если ValidateAntiForgeryToken атрибут применяется на контроллерах приложения, его можно переопределить с помощью IgnoreAntiforgeryToken атрибута.If the ValidateAntiForgeryToken attribute is applied across the app's controllers, it can be overridden with the IgnoreAntiforgeryToken attribute.

Примечание

ASP.NET Core не поддерживает добавление маркеры против подделки запросов GET автоматически.ASP.NET Core doesn't support adding antiforgery tokens to GET requests automatically.

Автоматически проверьте против подделки маркеры на предмет только небезопасных методов HTTPAutomatically validate antiforgery tokens for unsafe HTTP methods only

Приложения ASP.NET Core не создают против подделки маркеры для безопасные методы HTTP (GET, HEAD, параметры и ТРАССИРОВКИ).ASP.NET Core apps don't generate antiforgery tokens for safe HTTP methods (GET, HEAD, OPTIONS, and TRACE). Вместо применения широко ValidateAntiForgeryToken атрибут и затем переопределение с помощью IgnoreAntiforgeryToken атрибуты, AutoValidateAntiforgeryToken атрибут может использоваться.Instead of broadly applying the ValidateAntiForgeryToken attribute and then overriding it with IgnoreAntiforgeryToken attributes, the AutoValidateAntiforgeryToken attribute can be used. Этот атрибут работает идентично ValidateAntiForgeryToken атрибут, за исключением того, что он не требует токены для запросов, выполненных с помощью следующих методов HTTP:This attribute works identically to the ValidateAntiForgeryToken attribute, except that it doesn't require tokens for requests made using the following HTTP methods:

  • GETGET
  • HEAD,HEAD
  • OPTIONSOPTIONS
  • TRACETRACE

Рекомендуется использовать AutoValidateAntiforgeryToken широко для сценариев, отличных от API.We recommend use of AutoValidateAntiforgeryToken broadly for non-API scenarios. Это гарантирует, что действия после защищены по умолчанию.This ensures POST actions are protected by default. Вместо этого должен игнорировать против подделки токенов по умолчанию, если не ValidateAntiForgeryToken применяется для отдельных методов действий.The alternative is to ignore antiforgery tokens by default, unless ValidateAntiForgeryToken is applied to individual action methods. Он более вероятно в этом сценарии для метода POST действие должно быть оставлено без защиты по ошибке, оставляя приложение уязвимым к CSRF-атакам.It's more likely in this scenario for a POST action method to be left unprotected by mistake, leaving the app vulnerable to CSRF attacks. Все сообщения, необходимо отправить маркер защиты от подделки.All POSTs should send the antiforgery token.

API-интерфейсы не имеют автоматический механизм для отправки не файл cookie частью маркера.APIs don't have an automatic mechanism for sending the non-cookie part of the token. Реализация, вероятно, зависит от реализации кода клиента.The implementation probably depends on the client code implementation. Ниже приведены некоторые примеры:Some examples are shown below:

Пример уровня класса.Class-level example:

[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{

Пример глобального.Global example:

services.AddMvc(options => 
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute()));

Переопределение глобальных или против подделки атрибутов контроллераOverride global or controller antiforgery attributes

IgnoreAntiforgeryToken фильтр позволяет избежать необходимости токен от подделки, для заданного действия (или контроллера).The IgnoreAntiforgeryToken filter is used to eliminate the need for an antiforgery token for a given action (or controller). При применении этого фильтра переопределяет ValidateAntiForgeryToken и AutoValidateAntiforgeryToken фильтрам, указанным на более высоком уровне (глобально или на контроллере).When applied, this filter overrides ValidateAntiForgeryToken and AutoValidateAntiforgeryToken filters specified at a higher level (globally or on a controller).

[Authorize]
[AutoValidateAntiforgeryToken]
public class ManageController : Controller
{
    [HttpPost]
    [IgnoreAntiforgeryToken]
    public async Task<IActionResult> DoSomethingSafe(SomeViewModel model)
    {
        // no antiforgery token required
    }
}

Маркеры обновления после проверки подлинностиRefresh tokens after authentication

Маркеры должны обновляться после проверки подлинности пользователя, перенаправляя пользователя к представлению или страницы Razor Pages.Tokens should be refreshed after the user is authenticated by redirecting the user to a view or Razor Pages page.

JavaScript, AJAX и одностраничные приложенияJavaScript, AJAX, and SPAs

В традиционных приложениях на базе HTML против подделки маркеры передаются на сервер с помощью скрытых полях формы.In traditional HTML-based apps, antiforgery tokens are passed to the server using hidden form fields. В современных приложений на базе JavaScript и одностраничные приложения много запросов выполняются программно.In modern JavaScript-based apps and SPAs, many requests are made programmatically. Эти запросы AJAX могут использовать другие технологии (например, заголовки запросов или файлы cookie) для отправки маркера.These AJAX requests may use other techniques (such as request headers or cookies) to send the token.

Если файлы cookie используются для хранения маркеров проверки подлинности и проверки подлинности запросов API, на сервере, CSRF может стать проблемой.If cookies are used to store authentication tokens and to authenticate API requests on the server, CSRF is a potential problem. Если локальное хранилище используется для сохранения токена, CSRF уязвимость может устранен, так как значения из локального хранилища не автоматически отправляются на сервер с каждым запросом.If local storage is used to store the token, CSRF vulnerability might be mitigated because values from local storage aren't sent automatically to the server with every request. Таким образом с помощью локального хранилища для хранения маркер защиты от подделки на клиенте, а также отправки маркера, как в заголовке запроса — это рекомендуемый подход.Thus, using local storage to store the antiforgery token on the client and sending the token as a request header is a recommended approach.

JavaScriptJavaScript

Использование JavaScript с представлениями, маркер могут создаваться с использованием службу в представлении.Using JavaScript with views, the token can be created using a service from within the view. Внедрить Microsoft.AspNetCore.Antiforgery.IAntiforgery службы в представления и вызовите GetAndStoreTokens:Inject the Microsoft.AspNetCore.Antiforgery.IAntiforgery service into the view and call GetAndStoreTokens:

@{
    ViewData["Title"] = "AJAX Demo";
}
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(Context).RequestToken;
    }
}

<input type="hidden" id="RequestVerificationToken" 
       name="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">

<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<div class="row">
    <p><input type="button" id="antiforgery" value="Antiforgery"></p>
    <script>
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (xhttp.readyState == XMLHttpRequest.DONE) {
                if (xhttp.status == 200) {
                    alert(xhttp.responseText);
                } else {
                    alert('There was an error processing the AJAX request.');
                }
            }
        };

        document.addEventListener('DOMContentLoaded', function() {
            document.getElementById("antiforgery").onclick = function () {
                xhttp.open('POST', '@Url.Action("Antiforgery", "Home")', true);
                xhttp.setRequestHeader("RequestVerificationToken", 
                    document.getElementById('RequestVerificationToken').value);
                xhttp.send();
            }
        });
    </script>
</div>

Такой подход избавляет от необходимости работать непосредственно с помощью параметра с сервера файлы cookie или их считывания из клиента.This approach eliminates the need to deal directly with setting cookies from the server or reading them from the client.

В предыдущем примере JavaScript считывается значение скрытого поля для заголовка AJAX POST.The preceding example uses JavaScript to read the hidden field value for the AJAX POST header.

JavaScript можно также маркеров доступа в файлы cookie и использовать содержимое этого файла cookie для создания заголовка со значением маркера.JavaScript can also access tokens in cookies and use the cookie's contents to create a header with the token's value.

context.Response.Cookies.Append("CSRF-TOKEN", tokens.RequestToken, 
    new Microsoft.AspNetCore.Http.CookieOptions { HttpOnly = false });

При условии, что скрипт запрашивает отправку маркера в заголовок, называемый X-CSRF-TOKEN, настроить службу против подделки искать X-CSRF-TOKEN заголовка:Assuming the script requests to send the token in a header called X-CSRF-TOKEN, configure the antiforgery service to look for the X-CSRF-TOKEN header:

services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");

В следующем примере используется JavaScript для выполнения запроса AJAX с соответствующий заголовок:The following example uses JavaScript to make an AJAX request with the appropriate header:

function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i <ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

var csrfToken = getCookie("CSRF-TOKEN");

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    if (xhttp.readyState == XMLHttpRequest.DONE) {
        if (xhttp.status == 200) {
            alert(xhttp.responseText);
        } else {
            alert('There was an error processing the AJAX request.');
        }
    }
};
xhttp.open('POST', '/api/password/changepassword', true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.setRequestHeader("X-CSRF-TOKEN", csrfToken);
xhttp.send(JSON.stringify({ "newPassword": "ReallySecurePassword999$$$" }));

AngularJSAngularJS

AngularJS используется соглашение по адресу CSRF.AngularJS uses a convention to address CSRF. Если сервер отправляет файл cookie с именем XSRF-TOKEN, AngularJS $http служба добавляет значение файла cookie в заголовке, когда он отправляет запрос к серверу.If the server sends a cookie with the name XSRF-TOKEN, the AngularJS $http service adds the cookie value to a header when it sends a request to the server. Этот процесс выполняется автоматически.This process is automatic. Заголовок не должен быть явно заданные на клиенте.The header doesn't need to be set in the client explicitly. Имя заголовка — X-XSRF-TOKEN.The header name is X-XSRF-TOKEN. Сервер должен обнаружить этот заголовок и проверить его содержимое.The server should detect this header and validate its contents.

Для API ASP.NET Core для работы с этим соглашением, в классе startup вашего приложения:For ASP.NET Core API to work with this convention in your application startup:

  • Настройте приложение, чтобы предоставить маркер в файл cookie с именем XSRF-TOKEN.Configure your app to provide a token in a cookie called XSRF-TOKEN.
  • Настроить службу против подделки искать заголовок с именем X-XSRF-TOKEN.Configure the antiforgery service to look for a header named X-XSRF-TOKEN.
public void Configure(IApplicationBuilder app, IAntiforgery antiforgery)
{
    app.Use(next => context =>
    {
        string path = context.Request.Path.Value;

        if (
            string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
            string.Equals(path, "/index.html", StringComparison.OrdinalIgnoreCase))
        {
            // The request token can be sent as a JavaScript-readable cookie, 
            // and Angular uses it by default.
            var tokens = antiforgery.GetAndStoreTokens(context);
            context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, 
                new CookieOptions() { HttpOnly = false });
        }

        return next(context);
    });
}

public void ConfigureServices(IServiceCollection services)
{
    // Angular's default header name for sending the XSRF token.
    services.AddAntiforgery(options => options.HeaderName = "X-XSRF-TOKEN");
}

Просмотреть или скачать образец кода (как скачивать)View or download sample code (how to download)

Расширение защиты от подделкиExtend antiforgery

IAntiForgeryAdditionalDataProvider типа позволяет разработчикам расширять поведение системы anti-CSRF, циклической обработки дополнительных данных в каждом маркере.The IAntiForgeryAdditionalDataProvider type allows developers to extend the behavior of the anti-CSRF system by round-tripping additional data in each token. GetAdditionalData метод вызывается каждый раз создается маркер поля, и возвращаемое значение внедрены в созданный маркер.The GetAdditionalData method is called each time a field token is generated, and the return value is embedded within the generated token. Разработчик может возвращать метку времени, nonce или любое другое значение, а затем вызвать ValidateAdditionalData проверить эти данные, когда маркер проверяется.An implementer could return a timestamp, a nonce, or any other value and then call ValidateAdditionalData to validate this data when the token is validated. Имя пользователя клиента внедренных в создаваемые маркеры, поэтому нет необходимости, чтобы включить эту информацию.The client's username is already embedded in the generated tokens, so there's no need to include this information. Если маркер содержит дополнительные данные, но не IAntiForgeryAdditionalDataProvider будет настроен, дополнительные данные не проверяются.If a token includes supplemental data but no IAntiForgeryAdditionalDataProvider is configured, the supplemental data isn't validated.

Дополнительные ресурсыAdditional resources