Evitare attacchi Cross-Site Request Forgery (XSRF/CSRF) in ASP.NET CorePrevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core

Dal Steve Smith, Fiyaz Hasan, e Rick AndersonBy Steve Smith, Fiyaz Hasan, and Rick Anderson

Richiesta intersito falsa (nota anche come XSRF o CSRF) è un attacco contro applicazioni ospitate sul web in base al quale un'app web dannoso può influenzare l'interazione tra un browser client e un'app web che considera attendibile tale browser.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. Questi attacchi sono possibili in quanto i browser web inviano alcuni tipi di token di autenticazione automaticamente con ogni richiesta a un sito Web.These attacks are possible because web browsers send some types of authentication tokens automatically with every request to a website. Questa forma di attacco è noto anche come un attacco di un solo clic oppure sessione puntato perché l'attacco sfrutta l'utente autenticato del precedentemente sessione.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.

Un esempio di un attacco CSRF:An example of a CSRF attack:

  1. Un utente accede a www.good-banking-site.com tramite autenticazione basata su form.A user signs into www.good-banking-site.com using forms authentication. Il server autentica l'utente e invia una risposta che include un cookie di autenticazione.The server authenticates the user and issues a response that includes an authentication cookie. Il sito è vulnerabile agli attacchi perché considera attendibili tutte le richieste che riceve con un cookie di autenticazione valido.The site is vulnerable to attack because it trusts any request that it receives with a valid authentication cookie.

  2. L'utente visita un sito dannoso, www.bad-crook-site.com.The user visits a malicious site, www.bad-crook-site.com.

    Il sito dannoso, www.bad-crook-site.com, contiene un form HTML simile al seguente: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>
    

    Si noti che il form action post per il sito vulnerabile, non per il sito dannoso.Notice that the form's action posts to the vulnerable site, not to the malicious site. Questa è la parte "intersito" di CSRF.This is the "cross-site" part of CSRF.

  3. L'utente seleziona il pulsante di invio.The user selects the submit button. Il browser invia la richiesta e include automaticamente i cookie di autenticazione per il dominio richiesto, 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. La richiesta viene eseguita di www.good-banking-site.com server con il contesto di autenticazione dell'utente e può eseguire qualsiasi azione che un utente autenticato è autorizzato a eseguire.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.

Oltre allo scenario in cui l'utente seleziona il pulsante per inviare il modulo, il sito dannoso è stato possibile:In addition to the scenario where the user selects the button to submit the form, the malicious site could:

  • Eseguire uno script che invia automaticamente il form.Run a script that automatically submits the form.
  • Inviare l'invio del modulo come una richiesta AJAX.Send the form submission as an AJAX request.
  • Nascondere il modulo usando lo stile CSS.Hide the form using CSS.

Questi scenari alternativi non richiedono qualsiasi azione e l'input dell'utente diverse da inizialmente visitando il sito dannoso.These alternative scenarios don't require any action or input from the user other than initially visiting the malicious site.

L'uso di HTTPS non impedire un attacco CSRF.Using HTTPS doesn't prevent a CSRF attack. Il sito dannoso può inviare un https://www.good-banking-site.com/ richiesta con la stessa semplicità può inviare una richiesta non sicura.The malicious site can send an https://www.good-banking-site.com/ request just as easily as it can send an insecure request.

Alcuni attacchi colpiscono che rispondono alle richieste GET, nel qual caso un tag di immagine può essere utilizzato per eseguire l'azione.Some attacks target endpoints that respond to GET requests, in which case an image tag can be used to perform the action. Questa forma di attacco è comune nei siti di forum che consentono le immagini, ma Blocca JavaScript.This form of attack is common on forum sites that permit images but block JavaScript. Le app che modificano lo stato per le richieste GET, in cui le variabili o le risorse vengono modificate, sono vulnerabili ad attacchi dannosi.Apps that change state on GET requests, where variables or resources are altered, are vulnerable to malicious attacks. Le richieste GET che modificano lo stato sono non sicure. Una procedura consigliata consiste nel non modificare mai lo stato in una richiesta GET.GET requests that change state are insecure. A best practice is to never change state on a GET request.

Attacchi CSRF, sono possibili con App web che usano i cookie per l'autenticazione perché:CSRF attacks are possible against web apps that use cookies for authentication because:

  • Browser archiviare i cookie emessi da un'app web.Browsers store cookies issued by a web app.
  • I cookie stored includono i cookie di sessione per gli utenti autenticati.Stored cookies include session cookies for authenticated users.
  • I browser inviano che tutti i cookie associati a un dominio all'app web di tutte le richieste indipendentemente dal modo in cui è stata generata la richiesta all'app all'interno del browser.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.

Tuttavia, gli attacchi CSRF non sono limitati a sfruttare i cookie.However, CSRF attacks aren't limited to exploiting cookies. Ad esempio, l'autenticazione di base e classificata sono anche vulnerabili.For example, Basic and Digest authentication are also vulnerable. Dopo che un utente accede con l'autenticazione di base o Digest, il browser invia automaticamente le credenziali finché la sessione† termina.After a user signs in with Basic or Digest authentication, the browser automatically sends the credentials until the session† ends.

†In questo contesto sessione fa riferimento alla sessione dal lato client durante il quale l'utente viene autenticato.†In this context, session refers to the client-side session during which the user is authenticated. È non correlata alle sessioni sul lato server oppure Middleware di ASP.NET Core sessione.It's unrelated to server-side sessions or ASP.NET Core Session Middleware.

Gli utenti possono proteggersi contro vulnerabilità CSRF adottando delle precauzioni:Users can guard against CSRF vulnerabilities by taking precautions:

  • Firma dell'App web di termine del loro utilizzo.Sign off of web apps when finished using them.
  • Periodicamente i cookie del browser non crittografato.Clear browser cookies periodically.

Tuttavia, le vulnerabilità CSRF sono fondamentalmente un problema dell'app web, non dell'utente finale.However, CSRF vulnerabilities are fundamentally a problem with the web app, not the end user.

Nozioni fondamentali di autenticazioneAuthentication fundamentals

L'autenticazione basata su cookie è una forma più diffusi di autenticazione.Cookie-based authentication is a popular form of authentication. Sistemi di autenticazione basata su token sono sempre più diffusi, in particolare per le applicazioni a pagina singola (SPAs).Token-based authentication systems are growing in popularity, especially for Single Page Applications (SPAs).

Quando un utente esegue l'autenticazione con nome utente e password, che siano emessi un token, contenente un ticket di autenticazione che può essere utilizzato per l'autenticazione e autorizzazione.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. Il token viene archiviato come rende un cookie associato a ogni richiesta del client.The token is stored as a cookie that accompanies every request the client makes. Generazione e la convalida questo cookie viene eseguita dal Middleware di autenticazione dei Cookie.Generating and validating this cookie is performed by the Cookie Authentication Middleware. Il middleware serializza un'entità utente in un cookie crittografato.The middleware serializes a user principal into an encrypted cookie. Nelle richieste successive, il middleware convalida il cookie, ricrea l'entità e assegna l'entità per il utente proprietà di HttpContext.On subsequent requests, the middleware validates the cookie, recreates the principal, and assigns the principal to the User property of HttpContext.

Autenticazione basata su tokenToken-based authentication

Quando un utente viene autenticato, che siano emessi token (non un token anti falsificazione).When a user is authenticated, they're issued a token (not an antiforgery token). Il token contiene informazioni sull'utente sotto forma di attestazioni o un token di riferimento che punta all'app per lo stato utente gestito nell'app.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. Quando un utente tenta di accedere a una risorsa che richiede l'autenticazione, il token viene inviato all'app con un'intestazione di autorizzazione aggiuntive sotto forma di token di connessione.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. In questo modo l'app senza stato.This makes the app stateless. In ogni richiesta successiva, il token viene passato nella richiesta per la convalida sul lato server.In each subsequent request, the token is passed in the request for server-side validation. Questo token non è crittografato; ha codificato.This token isn't encrypted; it's encoded. Nel server, il token viene decodificato per accedere alle relative informazioni.On the server, the token is decoded to access its information. Per inviare il token nelle richieste successive, archiviare il token nell'archiviazione locale del browser.To send the token on subsequent requests, store the token in the browser's local storage. Non c'è da preoccuparsi delle vulnerabilità CSRF se il token viene memorizzato nell'archivio locale del browser.Don't be concerned about CSRF vulnerability if the token is stored in the browser's local storage. CSRF costituisce un problema quando il token viene archiviato in un cookie.CSRF is a concern when the token is stored in a cookie.

Più App ospitata in un dominioMultiple apps hosted at one domain

Ambienti di hosting condivisi sono vulnerabili a Hijack della sessione, account di accesso CSRF e altri attacchi.Shared hosting environments are vulnerable to session hijacking, login CSRF, and other attacks.

Sebbene example1.contoso.net e example2.contoso.net sono diversi host, c'è una relazione di trust implicita tra gli host sotto il *.contoso.net dominio.Although example1.contoso.net and example2.contoso.net are different hosts, there's an implicit trust relationship between hosts under the *.contoso.net domain. Questa relazione di trust implicita consente agli host potenzialmente non attendibili influire sul reciproci cookie (i criteri di corrispondenza dell'origine che regolano le richieste AJAX non vengono necessariamente applicano per i 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).

Per impedire gli attacchi che sfruttano i cookie attendibili tra le app ospitate nello stesso dominio, è possono non condivide i domini.Attacks that exploit trusted cookies between apps hosted on the same domain can be prevented by not sharing domains. Quando ogni app è ospitata nel proprio dominio, non vi è alcuna relazione di trust implicita cookie da sfruttare.When each app is hosted on its own domain, there is no implicit cookie trust relationship to exploit.

Configurazione anti falsificazione di ASP.NET CoreASP.NET Core antiforgery configuration

Avviso

ASP.NET Core implementa tramite anti falsificazione protezione di dati di ASP.NET Core.ASP.NET Core implements antiforgery using ASP.NET Core Data Protection. Lo stack di protezione dati deve essere configurato per funzionare in una server farm.The data protection stack must be configured to work in a server farm. Visualizzare configurazione della protezione dati per altre informazioni.See Configuring data protection for more information.

In ASP.NET Core 2.0 o versioni successive, il FormTagHelper inserisce il token anti falsificazione in elementi del form HTML.In ASP.NET Core 2.0 or later, the FormTagHelper injects antiforgery tokens into HTML form elements. Il markup seguente in un file Razor genera automaticamente i token anti falsificazione:The following markup in a Razor file automatically generates antiforgery tokens:

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

Analogamente, IHtmlHelper.BeginForm genera token antifalsificazione per impostazione predefinita, se il metodo del form non GET.Similarly, IHtmlHelper.BeginForm generates antiforgery tokens by default if the form's method isn't GET.

La generazione automatica dei token antifalsificazione per elementi del form HTML si verifica quando la <form> tag contiene il method="post" attributo e uno dei modi seguenti sono vere: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:

  • L'attributo action è vuoto (action="").The action attribute is empty (action="").
  • Non è specificato l'attributo di azione (<form method="post">).The action attribute isn't supplied (<form method="post">).

È possibile disabilitare la generazione automatica dei token antifalsificazione per elementi del form HTML:Automatic generation of antiforgery tokens for HTML form elements can be disabled:

  • Disabilitare in modo esplicito i token antifalsificazione con il asp-antiforgery attributo:Explicitly disable antiforgery tokens with the asp-antiforgery attribute:

    <form method="post" asp-antiforgery="false">
        ...
    </form>
    
  • L'elemento del form viene scelto esplicitamente di helper Tag usando l'Helper Tag ! esclusione simboli:The form element is opted-out of Tag Helpers by using the Tag Helper ! opt-out symbol:

    <!form method="post">
        ...
    </!form>
    
  • Rimuovere il FormTagHelper dalla vista.Remove the FormTagHelper from the view. Il FormTagHelper può essere rimosso da una vista aggiungendo la seguente direttiva per la visualizzazione 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
    

Nota

Razor Pages vengono protetti automaticamente dalle XSRF/CSRF.Razor Pages are automatically protected from XSRF/CSRF. Per altre informazioni, vedere XSRF/CSRF e Razor Pages.For more information, see XSRF/CSRF and Razor Pages.

L'approccio più comune per difendersi dagli attacchi CSRF consiste nell'usare la modello di sincronizzazione del Token (STP).The most common approach to defending against CSRF attacks is to use the Synchronizer Token Pattern (STP). STP viene usato quando l'utente richiede una pagina con i dati del modulo:STP is used when the user requests a page with form data:

  1. Il server invia un token associato all'identità dell'utente corrente al client.The server sends a token associated with the current user's identity to the client.
  2. Il client invia il token al server per la verifica.The client sends back the token to the server for verification.
  3. Se il server riceve un token che non corrisponde all'identità dell'utente autenticato, la richiesta viene rifiutata.If the server receives a token that doesn't match the authenticated user's identity, the request is rejected.

Il token è univoco e imprevedibili.The token is unique and unpredictable. Il token è anche utilizzabile per verificare che la sequenza appropriata di una serie di richieste (ad esempio, garantendo la sequenza di richiesta di: pagina 1 – pagina 2 – pagina 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). Tutti i moduli nei modelli di ASP.NET Core MVC e Razor Pages di generare token antifalsificazione.All of the forms in ASP.NET Core MVC and Razor Pages templates generate antiforgery tokens. La seguente coppia di Visualizza esempi genera token anti falsificazione:The following pair of view examples generate antiforgery tokens:

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

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

Aggiungere in modo esplicito un token anti falsificazione a un <form> elemento senza usare gli helper Tag con l'helper 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>

In ognuno dei casi precedenti, ASP.NET Core aggiunge un campo del form nascosto simile al seguente: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 include tre filtri per l'utilizzo di token anti falsificazione:ASP.NET Core includes three filters for working with antiforgery tokens:

Opzioni di anti falsificazioneAntiforgery options

Personalizzare opzioni di anti falsificazione in 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;
});

†Impostare l'anti falsificazione Cookie delle proprietà usando la proprietà dell'oggetto di CookieBuilder classe.†Set the antiforgery Cookie properties using the properties of the CookieBuilder class.

OpzioneOption DescrizioneDescription
CookieCookie Determina le impostazioni utilizzate per creare i cookie antifalsificazione.Determines the settings used to create the antiforgery cookies.
FormFieldNameFormFieldName Il nome del campo del form nascosto utilizzato dal sistema antifalsificazione per il rendering di un token anti falsificazione in viste.The name of the hidden form field used by the antiforgery system to render antiforgery tokens in views.
HeaderNameHeaderName Il nome dell'intestazione utilizzato dal sistema antifalsificazione.The name of the header used by the antiforgery system. Se null, il sistema prende in considerazione solo i dati del modulo.If null, the system considers only form data.
SuppressXFrameOptionsHeaderSuppressXFrameOptionsHeader Specifica se eliminare la generazione del X-Frame-Options intestazione.Specifies whether to suppress generation of the X-Frame-Options header. Per impostazione predefinita, l'intestazione viene generato con un valore di "SAMEORIGIN".By default, the header is generated with a value of "SAMEORIGIN". Il valore predefinito è 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;
});
OpzioneOption DescrizioneDescription
CookieCookie Determina le impostazioni utilizzate per creare i cookie antifalsificazione.Determines the settings used to create the antiforgery cookies.
CookieDomainCookieDomain Il dominio del cookie.The domain of the cookie. Il valore predefinito è null.Defaults to null. Questa proprietà è obsoleta e verrà rimossa in una versione futura.This property is obsolete and will be removed in a future version. L'alternativa consigliata è Cookie.Domain.The recommended alternative is Cookie.Domain.
CookieNameCookieName Il nome del cookie.The name of the cookie. Se non impostato, il sistema genera un nome univoco che inizia con la DefaultCookiePrefix (". AspNetCore.Antiforgery.").If not set, the system generates a unique name beginning with the DefaultCookiePrefix (".AspNetCore.Antiforgery."). Questa proprietà è obsoleta e verrà rimossa in una versione futura.This property is obsolete and will be removed in a future version. L'alternativa consigliata è Cookie.Name.The recommended alternative is Cookie.Name.
CookiePathCookiePath Il percorso impostato nel cookie.The path set on the cookie. Questa proprietà è obsoleta e verrà rimossa in una versione futura.This property is obsolete and will be removed in a future version. L'alternativa consigliata è Cookie.Path.The recommended alternative is Cookie.Path.
FormFieldNameFormFieldName Il nome del campo del form nascosto utilizzato dal sistema antifalsificazione per il rendering di un token anti falsificazione in viste.The name of the hidden form field used by the antiforgery system to render antiforgery tokens in views.
HeaderNameHeaderName Il nome dell'intestazione utilizzato dal sistema antifalsificazione.The name of the header used by the antiforgery system. Se null, il sistema prende in considerazione solo i dati del modulo.If null, the system considers only form data.
RequireSslRequireSsl Specifica se il sistema antifalsificazione richiede HTTPS.Specifies whether HTTPS is required by the antiforgery system. Se true, non HTTPS richieste hanno esito negativo.If true, non-HTTPS requests fail. Il valore predefinito è false.Defaults to false. Questa proprietà è obsoleta e verrà rimossa in una versione futura.This property is obsolete and will be removed in a future version. L'alternativa consigliata consiste nell'impostare Cookie.SecurePolicy.The recommended alternative is to set Cookie.SecurePolicy.
SuppressXFrameOptionsHeaderSuppressXFrameOptionsHeader Specifica se eliminare la generazione del X-Frame-Options intestazione.Specifies whether to suppress generation of the X-Frame-Options header. Per impostazione predefinita, l'intestazione viene generato con un valore di "SAMEORIGIN".By default, the header is generated with a value of "SAMEORIGIN". Il valore predefinito è false.Defaults to false.

Per altre informazioni, vedere CookieAuthenticationOptions.For more information, see CookieAuthenticationOptions.

Configurare le funzionalità anti falsificazione con IAntiforgeryConfigure antiforgery features with IAntiforgery

IAntiforgery fornisce l'API per configurare le funzionalità di anti falsificazione.IAntiforgery provides the API to configure antiforgery features. IAntiforgery può essere richiesta nel Configure metodo di Startup classe.IAntiforgery can be requested in the Configure method of the Startup class. L'esempio seguente usa middleware dalla home page dell'app per generare un token anti falsificazione e inviarlo nella risposta sotto forma di cookie (tramite l'impostazione predefinita Angular convenzione di denominazione descritta più avanti in questo argomento):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);
    });
}

Richiedere la convalida antifalsificazioneRequire antiforgery validation

ValidateAntiForgeryToken è un filtro azione che può essere applicato a una singola azione, un controller o a livello globale.ValidateAntiForgeryToken is an action filter that can be applied to an individual action, a controller, or globally. Le richieste effettuate alle azioni che hanno applicato questo filtro vengono bloccate a meno che la richiesta include un token anti falsificazione valido.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 });
}

Il ValidateAntiForgeryToken attributo richiede un token per le richieste ai metodi di azione che decora, tra cui le richieste HTTP GET.The ValidateAntiForgeryToken attribute requires a token for requests to the action methods it decorates, including HTTP GET requests. Se il ValidateAntiForgeryToken attributo è applicato tra controller dell'app, che può essere sostituito con il IgnoreAntiforgeryToken attributo.If the ValidateAntiForgeryToken attribute is applied across the app's controllers, it can be overridden with the IgnoreAntiforgeryToken attribute.

Nota

ASP.NET Core non supporta l'aggiunta di token anti falsificazione alle richieste GET automaticamente.ASP.NET Core doesn't support adding antiforgery tokens to GET requests automatically.

Convalidare automaticamente i token antifalsificazione per solo i metodi HTTP non sicuriAutomatically validate antiforgery tokens for unsafe HTTP methods only

Le app ASP.NET Core non generano i token antifalsificazione per safe metodi HTTP (GET, HEAD, opzioni e traccia).ASP.NET Core apps don't generate antiforgery tokens for safe HTTP methods (GET, HEAD, OPTIONS, and TRACE). Anziché applicare ampiamente la ValidateAntiForgeryToken attributo e quindi si esegue l'override con IgnoreAntiforgeryToken attributi, la AutoValidateAntiforgeryToken attributo può essere utilizzato.Instead of broadly applying the ValidateAntiForgeryToken attribute and then overriding it with IgnoreAntiforgeryToken attributes, the AutoValidateAntiforgeryToken attribute can be used. Questo attributo funziona in modo identico al ValidateAntiForgeryToken attributo, ad eccezione del fatto che non richiede token per le richieste effettuate usando i metodi HTTP seguenti:This attribute works identically to the ValidateAntiForgeryToken attribute, except that it doesn't require tokens for requests made using the following HTTP methods:

  • GETGET
  • HEADHEAD
  • OPZIONIOPTIONS
  • TRACETRACE

È consigliabile usare AutoValidateAntiforgeryToken su vasta scala per gli scenari non-API.We recommend use of AutoValidateAntiforgeryToken broadly for non-API scenarios. In questo modo le azioni POST sono protetti per impostazione predefinita.This ensures POST actions are protected by default. In alternativa è possibile ignorare i token antifalsificazione per impostazione predefinita, a meno che non ValidateAntiForgeryToken viene applicata a singoli metodi di azione.The alternative is to ignore antiforgery tokens by default, unless ValidateAntiForgeryToken is applied to individual action methods. È più probabile che in questo scenario per un metodo di azione POST deve rimanere non protetto per errore, uscire dall'app vulnerabile agli attacchi 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. Tutti i post devono inviare il token antifalsificazione.All POSTs should send the antiforgery token.

Le API non sono un meccanismo automatico per inviare la parte non cookie del token.APIs don't have an automatic mechanism for sending the non-cookie part of the token. L'implementazione dipende probabilmente dall'implementazione del codice client.The implementation probably depends on the client code implementation. Di seguito sono riportati alcuni esempi:Some examples are shown below:

Esempio a livello di classe:Class-level example:

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

Esempio globale:Global example:

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

Override globale o controller anti falsificazione attributiOverride global or controller antiforgery attributes

Il IgnoreAntiforgeryToken filtro viene utilizzato per eliminare la necessità di un token anti falsificazione per una determinata azione (o controller).The IgnoreAntiforgeryToken filter is used to eliminate the need for an antiforgery token for a given action (or controller). Quando applicata, esegue l'override di questo filtro ValidateAntiForgeryToken e AutoValidateAntiforgeryToken filtri specificati a un livello superiore (a livello globale o in un controller).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
    }
}

Token di aggiornamento dopo l'autenticazioneRefresh tokens after authentication

I token devono essere aggiornati dopo che l'utente viene autenticato, reindirizzare l'utente a una pagina Razor Pages o una vista.Tokens should be refreshed after the user is authenticated by redirecting the user to a view or Razor Pages page.

JavaScript, AJAX e SPA (Single Page Application)JavaScript, AJAX, and SPAs

Nelle App basate su HTML tradizionale, i token anti falsificazione vengono passati al server usando i campi modulo nascosti.In traditional HTML-based apps, antiforgery tokens are passed to the server using hidden form fields. Nell'App moderne basate su JavaScript e SPAs, molte richieste vengono effettuate a livello di codice.In modern JavaScript-based apps and SPAs, many requests are made programmatically. Queste richieste AJAX possono utilizzare altre tecniche, quali intestazioni della richiesta o i cookie, inviare il token.These AJAX requests may use other techniques (such as request headers or cookies) to send the token.

Se i cookie vengono usati per archiviare i token di autenticazione e per autenticare le richieste di API sul server, CSRF è un potenziale problema.If cookies are used to store authentication tokens and to authenticate API requests on the server, CSRF is a potential problem. Se l'archiviazione locale viene usata per archiviare il token, CSRF vulnerabilità potrebbe essere ridotta perché i valori dall'archiviazione locale non vengono inviati automaticamente al server con ogni richiesta.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. Di conseguenza, usando un'archiviazione locale per archiviare il token anti falsificazione sul client che invia il token come intestazione della richiesta è un approccio consigliato.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

Utilizzo di JavaScript con visualizzazioni, il token è possibile creare usando un servizio dall'interno della visualizzazione.Using JavaScript with views, the token can be created using a service from within the view. Inserire il Microsoft.AspNetCore.Antiforgery.IAntiforgery servizio nella visualizzazione e chiamare 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>

Questo approccio elimina la necessità di interagire direttamente con l'impostazione di cookie dal server o la relativa lettura dai client.This approach eliminates the need to deal directly with setting cookies from the server or reading them from the client.

L'esempio precedente Usa JavaScript per leggere il valore del campo nascosto per l'intestazione di AJAX POST.The preceding example uses JavaScript to read the hidden field value for the AJAX POST header.

JavaScript è possibile anche i token nei cookie di accesso e usare il contenuto del cookie per creare un'intestazione con il valore del token.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 });

Supponendo che lo script richiede di inviare il token in un'intestazione denominata X-CSRF-TOKEN, configurare il servizio anti falsificazione per cercare il X-CSRF-TOKEN intestazione: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");

L'esempio seguente usa JavaScript per eseguire una richiesta AJAX con l'intestazione appropriata: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 Usa una convenzione all'indirizzo CSRF.AngularJS uses a convention to address CSRF. Se il server invia un cookie con il nome XSRF-TOKEN, AngularJS $http servizio aggiunge il valore del cookie a un'intestazione quando viene inviata una richiesta al server.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. Questo processo è automatico.This process is automatic. L'intestazione non deve essere impostata in modo esplicito nel client.The header doesn't need to be set in the client explicitly. È il nome dell'intestazione X-XSRF-TOKEN.The header name is X-XSRF-TOKEN. Il server deve rilevare questa intestazione e convalidare il contenuto.The server should detect this header and validate its contents.

Per ASP.NET Core API da usare con questa convenzione nell'avvio dell'applicazione:For ASP.NET Core API to work with this convention in your application startup:

  • Configurare l'app per fornire un token in un cookie denominato XSRF-TOKEN.Configure your app to provide a token in a cookie called XSRF-TOKEN.
  • Configurare il servizio per individuare un'intestazione denominata anti falsificazione 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");
}

Visualizzare o scaricare il codice di esempio (procedura per il download)View or download sample code (how to download)

Estendere anti falsificazioneExtend antiforgery

Il IAntiForgeryAdditionalDataProvider tipo consente agli sviluppatori di estendere il comportamento del sistema Intersito, i dati aggiuntivi di andata e ritorno in ogni token.The IAntiForgeryAdditionalDataProvider type allows developers to extend the behavior of the anti-CSRF system by round-tripping additional data in each token. Il GetAdditionalData viene chiamato ogni volta che viene generato un token di campo e il valore restituito è incorporato all'interno del token generato.The GetAdditionalData method is called each time a field token is generated, and the return value is embedded within the generated token. Un implementatore potrebbe restituire un timestamp, un parametro nonce o qualsiasi altro valore, quindi chiamare ValidateAdditionalData per convalidare i dati quando il token viene convalidato.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. Nome utente del client è già incorporato nei token generati, pertanto non è necessario includere queste informazioni.The client's username is already embedded in the generated tokens, so there's no need to include this information. Se un token include dati aggiuntivi, ma non IAntiForgeryAdditionalDataProvider è configurato, non vero convalidati dati aggiuntivi.If a token includes supplemental data but no IAntiForgeryAdditionalDataProvider is configured, the supplemental data isn't validated.

Risorse aggiuntiveAdditional resources