Prevenzione di XSRF/CSRF in ASP.NET MVC e pagine WebXSRF/CSRF Prevention in ASP.NET MVC and Web Pages

di Rick Andersonby Rick Anderson

La richiesta tra siti falsificata (nota anche come XSRF o CSRF) è un attacco contro le applicazioni ospitate sul Web, in cui un sito Web dannoso può influenzare l'interazione tra un browser client e un sito web considerato attendibile da tale browser.Cross-site request forgery (also known as XSRF or CSRF) is an attack against web-hosted applications whereby a malicious web site can influence the interaction between a client browser and a web site trusted by that browser. Questi attacchi sono possibili perché i Web browser invieranno automaticamente i token di autenticazione con ogni richiesta a un sito Web.These attacks are made possible because web browsers will send authentication tokens automatically with every request to a web site. Un classico esempio è un cookie di autenticazione, ad esempio un ticket di autenticazione basata su form di ASP.NET.The canonical example is an authentication cookie, such as ASP.NET's Forms Authentication ticket. Tuttavia, i siti Web che utilizzano qualsiasi meccanismo di autenticazione permanente, ad esempio l'autenticazione di Windows, di base e così via, possono essere assegnati a tali attacchi.However, web sites which use any persistent authentication mechanism (such as Windows Authentication, Basic, and so forth) can be targeted by these attacks.

Un attacco XSRF è diverso da un attacco di phishing.An XSRF attack is distinct from a phishing attack. Gli attacchi di phishing richiedono un'interazione da parte della vittima.Phishing attacks require interaction from the victim. In un attacco di phishing, un sito Web dannoso simula il sito Web di destinazione e la vittima è ingannata a fornire informazioni riservate all'autore dell'attacco.In a phishing attack, a malicious web site will mimic the target web site, and the victim is fooled into providing sensitive information to the attacker. In un attacco XSRF spesso non è necessaria alcuna interazione da parte della vittima.In an XSRF attack, there is often no interaction necessary from the victim. Piuttosto, l'autore dell'attacco si basa sul browser che invia automaticamente tutti i cookie pertinenti al sito Web di destinazione.Rather, the attacker is relying on the browser automatically sending all relevant cookies to the destination web site.

Per ulteriori informazioni, vedere Open Web Application Security Project(OWASP) XSRF.For more information, see the Open Web Application Security Project(OWASP) XSRF.

Anatomia di un attaccoAnatomy of an attack

Per esaminare un attacco XSRF, considerare un utente che desidera eseguire alcune transazioni online bancarie.To walk through an XSRF attack, consider a user who wants to perform some online banking transactions. Questo utente visita prima WoodgroveBank.com e accede, a quel punto l'intestazione della risposta conterrà il cookie di autenticazione:This user first visits WoodgroveBank.com and logs in, at which point the response header will contain her authentication cookie:

HTTP/1.1 200 OK
Date: Mon, 18 Jun 2012 21:22:33 GMT
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH={authentication-token}; path=/; secure; HttpOnly;
{ Cache-Control, Content-Type, Location, Server and other keys/values not listed. }

Poiché il cookie di autenticazione è un cookie di sessione, verrà automaticamente cancellato dal browser quando il processo del browser viene chiuso.Because the authentication cookie is a session cookie, it will be automatically cleared by the browser when the browser process exits. Tuttavia, fino a quel momento, il browser includerà automaticamente il cookie con ogni richiesta a WoodgroveBank.com.However, until that time, the browser will automatically include the cookie with each request to WoodgroveBank.com. L'utente ora desidera trasferire $1000 a un altro account, quindi compila un modulo nel sito bancario e il browser esegue questa richiesta al server:The user now wants to transfer $1000 to another account, so she fills out a form on the banking site, and the browser makes this request to the server:

POST /DoTransfer HTTP/1.1
Host: WoodgroveBank.com
Content-Type: application/x-www-form-urlencoded
Cookie: .ASPXAUTH={authentication-token}
toAcct=12345&amount=1,000.00

Poiché questa operazione ha un effetto collaterale (avvia una transazione monetaria), il sito bancario ha scelto di richiedere un HTTP POST per poter avviare questa operazione.Because this operation has a side effect (it initiates a monetary transaction), the banking site has chosen to require an HTTP POST in order to initiate this operation. Il server legge il token di autenticazione dalla richiesta, Cerca il numero di account dell'utente corrente, verifica che esistano fondi sufficienti, quindi avvia la transazione nell'account di destinazione.The server reads the authentication token from the request, looks up the current user's account number, verifies that sufficient funds exist, and then initiates the transaction into the destination account.

Il tuo online banking è stato completato, l'utente si sposta dal sito bancario e visita altre località sul Web.Her online banking complete, the user navigates away from the banking site and visits other locations on the web. Uno di questi siti, fabrikam.com, include il markup seguente in una pagina incorporata all'interno di un <iframe>:One of those sites – fabrikam.com – includes the following markup on a page embedded within an <iframe>:

<form id="theForm" action="https://WoodgroveBank.com/DoTransfer" method="post">
    <input type="hidden" name="toAcct" value="67890" />
    <input type="hidden" name="amount" value="250.00" />
</form>
<script type="text/javascript">
    document.getElementById('theForm').submit();
</script>

Che quindi fa in modo che il browser effettui questa richiesta:Which then causes the browser to make this request:

POST /DoTransfer HTTP/1.1
Host: WoodgroveBank.com
Content-Type: application/x-www-form-urlencoded
Cookie: .ASPXAUTH={authentication-token}
toAcct=67890&amount=250.00

L'autore dell'attacco sta sfruttando il fatto che l'utente potrebbe ancora avere un token di autenticazione valido per il sito Web di destinazione e usa un piccolo frammento di codice JavaScript per fare in modo che il browser renda automaticamente un HTTP POST al sito di destinazione.The attacker is exploiting the fact that the user might still have a valid authentication token for the target web site, and she is using a small snippet of Javascript to cause the browser to make an HTTP POST to the target site automatically. Se il token di autenticazione è ancora valido, il sito bancario avvierà un trasferimento di $250 nell'account dell'utente malintenzionato scegliendo.If the authentication token is still valid, the banking site will initiate a transfer of $250 into the account of the attacker's choosing.

Mitigazioni inefficaciIneffective mitigations

È interessante notare che nello scenario precedente il fatto che WoodgroveBank.com è stato eseguito l'accesso tramite SSL e che un cookie di autenticazione solo SSL non era sufficiente per contrastare l'attacco.It is interesting to note that in the above scenario, the fact that WoodgroveBank.com was being accessed via SSL and had an SSL-only authentication cookie was insufficient to thwart the attack. L'utente malintenzionato è in grado di specificare lo schema URI (HTTPS) nell'elemento <form> e il browser continuerà a inviare cookie non scaduti al sito di destinazione, purché tali cookie siano coerenti con lo schema URI della destinazione prevista.The attacker is able to specify the URI scheme (https) in her <form> element, and the browser will continue to send unexpired cookies to the target site as long as those cookies are consistent with the URI scheme of the intended target.

Si può affermare che l'utente non deve semplicemente visitare i siti non attendibili, perché la visita solo dei siti attendibili consente di mantenere la sicurezza online.One could argue that the user should simply not visit untrusted sites, as visiting only trusted sites is helps to remain safe online. Esistono alcune verità, ma sfortunatamente questo Consiglio non è sempre pratico.There is some truth to this, but unfortunately this advice is not always practical. Probabilmente l'utente "considera attendibile" il sito delle notizie locali ConsolidatedMessenger.Perhaps the user "trusts" the local news site ConsolidatedMessenger. ConsolidatedMessenger.com e visita invece il sito, ma il sito ha una vulnerabilità XSS che consente a un utente malintenzionato di inserire lo stesso frammento di codice in esecuzione in fabrikam.com.ConsolidatedMessenger.com and goes to visit that site instead, but that site has an XSS vulnerability which allows an attacker to inject the same snippet of code that was running on fabrikam.com.

È possibile verificare che le richieste in ingresso dispongano di un' intestazione Referer che fa riferimento al dominio.You can verify that incoming requests have a Referer header referencing your domain. Questa operazione arresterà le richieste involontariamente inviate da un dominio di terze parti.This will stop requests unwittingly submitted from a third-party domain. Tuttavia, alcune persone disabilitano l'intestazione del referer del browser per motivi di privacy e talvolta gli utenti malintenzionati possono falsificare tale intestazione se la vittima dispone di un software non sicuro installato.However, some people disable their browser's Referer header for privacy reasons, and attackers can sometimes spoof that header if the victim has certain insecure software installed. La verifica dell' intestazione del referer non è considerata un approccio sicuro per impedire attacchi XSRF.Verifying the Referer header is not considered a secure approach to preventing XSRF attacks.

Mitigazioni XSRF di runtime dello stack WebWeb Stack Runtime XSRF mitigations

Il runtime di ASP.NET Web stack usa una variante del modello di token di sincronizzazione per difendersi dagli attacchi XSRF.The ASP.NET Web Stack Runtime uses a variant of the synchronizer token pattern to defend against XSRF attacks. Il formato generale del modello di token di sincronizzazione è che due token anti-XSRF vengono inviati al server con ogni HTTP POST (oltre al token di autenticazione): un token come cookie e l'altro come valore del modulo.The general form of the synchronizer token pattern is that two anti-XSRF tokens are submitted to the server with each HTTP POST (In addition to the authentication token): one token as a cookie, and the other as a form value. I valori dei token generati dal runtime ASP.NET non sono deterministici o prevedibili da un utente malintenzionato.The token values generated by the ASP.NET runtime are not deterministic or predictable by an attacker. Quando vengono inviati i token, il server consentirà alla richiesta di procedere solo se entrambi i token superano un controllo di confronto.When the tokens are submitted, the server will allow the request to proceed only if both tokens pass a comparison check.

Il token della sessione di verifica della richiesta XSRF viene archiviato come cookie HTTP e attualmente contiene le informazioni seguenti nel payload:The XSRF request verification session token is stored as an HTTP cookie and currently contains the following information in its payload:

  • Token di sicurezza costituito da un identificatore casuale a 128 bit.A security token, consisting of a random 128-bit identifier.
    La figura seguente mostra il token della sessione di verifica della richiesta XSRF visualizzato con gli strumenti di sviluppo F12 di Internet Explorer: (si noti che questa è l'implementazione corrente ed è soggetta, anche probabilmente, a modificare).The following image shows the XSRF request verification session token displayed with the Internet Explorer F12 developer tools: (Note this is the current implementation and is subject, even likely, to change.)

Il token del campo viene archiviato come <input type="hidden" /> e contiene le informazioni seguenti nel payload:The field token is stored as an <input type="hidden" /> and contains the following information in its payload:

I payload dei token anti-XSRF sono crittografati e firmati, pertanto non è possibile visualizzare il nome utente quando si usano gli strumenti per esaminare i token.The payloads of the anti-XSRF tokens are encrypted and signed, so you can't view the username when using tools to examine the tokens. Quando l'applicazione Web è destinata a ASP.NET 4,0, i servizi di crittografia sono forniti dalla routine machineKey. Encode .When the web application is targeting ASP.NET 4.0, cryptographic services are provided by the MachineKey.Encode routine. Quando l'applicazione Web è destinata a ASP.NET 4,5 o versione successiva, i servizi di crittografia sono forniti dalla routine machineKey. Protect , che offre prestazioni migliori, estendibilità e sicurezza.When the web application is targeting ASP.NET 4.5 or higher, cryptographic services are provided by the MachineKey.Protect routine, which offers better performance, extensibility, and security. Per altri dettagli, vedere i post di Blog seguenti:See the following blog posts for more details:

Generazione dei tokenGenerating the tokens

Per generare i token anti-XSRF, chiamare il metodo @Html.AntiForgeryToken da una visualizzazione MVC o @AntiForgery.GetHtml() da una pagina Razor.To generate the anti-XSRF tokens, call the @Html.AntiForgeryToken method from an MVC view or @AntiForgery.GetHtml() from a Razor page. Il runtime eseguirà quindi i passaggi seguenti:The runtime will then perform the following steps:

  1. Se la richiesta HTTP corrente contiene già un token di sessione anti-XSRF (il cookie anti-XSRF __RequestVerificationToken), il token di sicurezza viene Estratto da tale token.If the current HTTP request already contains an anti-XSRF session token (the anti-XSRF cookie __RequestVerificationToken), the security token is extracted from it. Se la richiesta HTTP non contiene un token di sessione anti-XSRF o se l'estrazione del token di sicurezza ha esito negativo, verrà generato un nuovo token anti-XSRF casuale.If the HTTP request does not contain an anti-XSRF session token or if extraction of the security token fails, a new random anti-XSRF token will be generated.
  2. Un token di campo anti-XSRF viene generato utilizzando il token di sicurezza del passaggio (1) precedente e l'identità dell'utente che ha eseguito l'accesso corrente.An anti-XSRF field token is generated using the security token from step (1) above and the identity of the current logged-in user. Per ulteriori informazioni sulla determinazione dell'identità utente, vedere la sezione scenari con supporto speciale di seguito. Inoltre, se è configurato un IAntiForgeryAdditionalDataProvider , il runtime chiamerà il relativo metodo GetAdditionalData e includerà la stringa restituita nel token del campo.(For more information on determining user identity, see the Scenarios with special support section below.) Additionally, if an IAntiForgeryAdditionalDataProvider is configured, the runtime will call its GetAdditionalData method and include the returned string in the field token. Per ulteriori informazioni, vedere la sezione relativa alla configurazione e all'estendibilità .(See the Configuration and extensibility section for more information.)
  3. Se è stato generato un nuovo token anti-XSRF nel passaggio (1), verrà creato un nuovo token di sessione che lo conterrà e verrà aggiunto alla raccolta di cookie HTTP in uscita.If a new anti-XSRF token was generated in step (1), a new session token will be created to contain it and will be added to the outbound HTTP cookies collection. Il token di campo del passaggio (2) verrà racchiuso in un elemento <input type="hidden" /> e il markup HTML sarà il valore restituito di Html.AntiForgeryToken() o AntiForgery.GetHtml().The field token from step (2) will be wrapped in an <input type="hidden" /> element, and this HTML markup will be the return value of Html.AntiForgeryToken() or AntiForgery.GetHtml().

Convalida dei tokenValidating the tokens

Per convalidare i token anti-XSRF in ingresso, lo sviluppatore include un attributo ValidateAntiForgeryToken sul suo controller o azione MVC oppure chiama @AntiForgery.Validate() dalla propria pagina Razor.To validate the incoming anti-XSRF tokens, the developer includes a ValidateAntiForgeryToken attribute on her MVC action or controller, or she calls @AntiForgery.Validate() from her Razor page. Il runtime eseguirà i passaggi seguenti:The runtime will perform the following steps:

  1. Il token di sessione in ingresso e il token di campo vengono letti e il token anti-XSRF Estratto da ciascuno.The incoming session token and field token are read and the anti-XSRF token extracted from each. I token anti-XSRF devono essere identici per ogni passaggio (2) nella routine di generazione.The anti-XSRF tokens must be identical per step (2) in the generation routine.
  2. Se l'utente corrente è autenticato, il suo nome utente viene confrontato con il nome utente archiviato nel token del campo.If the current user is authenticated, her username is compared with the username stored in the field token. I nomi utente devono corrispondere.The usernames must match.
  3. Se è configurato un IAntiForgeryAdditionalDataProvider , il runtime chiama il relativo metodo ValidateAdditionalData .If an IAntiForgeryAdditionalDataProvider is configured, the runtime calls its ValidateAdditionalData method. Il metodo deve restituire il valore booleano true.The method must return the Boolean value true.

Se la convalida ha esito positivo, la richiesta può continuare.If validation succeeds, the request is allowed to proceed. Se la convalida ha esito negativo, il Framework genererà un HttpAntiForgeryException.If validation fails, the framework will throw an HttpAntiForgeryException.

Condizioni di erroreFailure conditions

A partire da ASP.NET Web stack Runtime V2, qualsiasi HttpAntiForgeryException generato durante la convalida conterrà informazioni dettagliate su ciò che si è verificato un errore.Starting with The ASP.NET Web Stack Runtime v2, any HttpAntiForgeryException that is thrown during validation will contain detailed information about what went wrong. Le condizioni di errore attualmente definite sono:The currently defined failure conditions are:

  • Il token di sessione o il token del form non è presente nella richiesta.The session token or form token is not present in the request.
  • Il token di sessione o il token del modulo non è leggibile.The session token or form token is unreadable. La causa più probabile è una farm che esegue versioni non corrispondenti del runtime dello stack Web ASP.NET o di una farm in cui l'elemento> <machineKey in Web. config è diverso tra i computer.The most likely cause of this is a farm running mismatched versions of The ASP.NET Web Stack Runtime or a farm where the <machineKey> element in Web.config differs between machines. È possibile utilizzare uno strumento come Fiddler per forzare questa eccezione manomettendo il token anti-XSRF.You can use a tool such as Fiddler to force this exception by tampering with either anti-XSRF token.
  • Il token di sessione e il token di campo sono stati scambiati.The session token and field token were swapped.
  • Il token di sessione e il token di campo contengono token di sicurezza non corrispondenti.The session token and field token contain mismatched security tokens.
  • Il nome utente incorporato nel token del campo non corrisponde al nome utente dell'utente connesso corrente.The username embedded within the field token does not match the current logged-in user's username.
  • Il metodo IAntiForgeryAdditionalDataProvider. ValidateAdditionalData ha restituito false.The IAntiForgeryAdditionalDataProvider.ValidateAdditionalData method returned false.

Le funzionalità anti-XSRF possono anche eseguire ulteriori verifiche durante la generazione o la convalida dei token e gli errori durante tali controlli possono causare la generazione di eccezioni.The anti-XSRF facilities may also perform additional checking during token generation or validation, and failures during these checks may result in exceptions being thrown. Per ulteriori informazioni, vedere le sezioni WIF/ACS/autenticazione basata su attestazioni e estendibilità ed estendibilità .See the WIF / ACS / claims-based authentication and Configuration and extensibility sections for more information.

Scenari con supporto specialeScenarios with special support

Autenticazione anonimaAnonymous authentication

Il sistema XSRF contiene un supporto speciale per gli utenti anonimi, in cui "Anonymous" viene definito come un utente in cui la proprietà IIdentity. IsAuthenticated restituisce false.The anti-XSRF system contains special support for anonymous users, where "anonymous" is defined as a user where the IIdentity.IsAuthenticated property returns false. Gli scenari includono la protezione XSRF per la pagina di accesso (prima dell'autenticazione dell'utente) e gli schemi di autenticazione personalizzati in cui l'applicazione usa un meccanismo diverso da IIdentity per identificare gli utenti.Scenarios include providing XSRF protection to the login page (before the user is authenticated) and custom authentication schemes where the application uses a mechanism other than IIdentity to identify users.

Per supportare questi scenari, tenere presente che i token di sessione e di campo sono uniti da un token di sicurezza, ovvero un identificatore opaco a 128 bit generato in modo casuale.To support these scenarios, recall that the session and field tokens are joined by a security token, which is a 128-bit randomly-generated opaque identifier. Questo token di sicurezza viene usato per tenere traccia di una sessione di un singolo utente mentre Esplora il sito, in modo che sia in grado di svolgere efficacemente lo scopo di un identificatore anonimo.This security token is used to track an individual user's session as she navigates the site, so it effectively serves the purpose of an anonymous identifier. Viene utilizzata una stringa vuota al posto del nome utente per le routine di generazione e convalida descritte in precedenza.An empty string is used in place of the username for the generation and validation routines described above.

WIF/ACS/autenticazione basata su attestazioniWIF / ACS / claims-based authentication

In genere, le classi IIdentity incorporate nel .NET Framework hanno la proprietà che IIdentity.Name è sufficiente per identificare in modo univoco un determinato utente all'interno di una particolare applicazione.Normally, the IIdentity classes built in to the .NET Framework have the property that IIdentity.Name is sufficient to uniquely identify a particular user within a particular application. Ad esempio, FormsIdentity.Name restituisce il nome utente archiviato nel database delle appartenenze (univoco per tutte le applicazioni a seconda del database), WindowsIdentity.Name restituisce l'identità dell'utente qualificata come dominio e così via.For example, FormsIdentity.Name returns the username stored in the membership database (which is unique for all applications depending on that database), WindowsIdentity.Name returns the domain-qualified identity of the user, and so on. Questi sistemi forniscono non solo l'autenticazione; identificano inoltre gli utenti di un'applicazione.These systems provide not only authentication; they also identify users to an application.

L'autenticazione basata sulle attestazioni, d'altra parte, non richiede necessariamente l'identificazione di un utente specifico.Claims-based authentication, on the other hand, does not necessarily require identifying a particular user. Al contrario, i tipi ClaimsPrincipal e ClaimsIdentity sono associati a un set di istanze di attestazione , dove le singole attestazioni potrebbero essere "è di 18 + anni di età" o "è un amministratore" per qualsiasi altro elemento.Instead, the ClaimsPrincipal and ClaimsIdentity types are associated with a set of Claim instances, where the individual claims might be "is 18+ years of age" or "is an administrator" to anything else. Poiché l'utente non è stato necessariamente identificato, il runtime non può utilizzare la proprietà ClaimsIdentity.Name come identificatore univoco per questo particolare utente.Since the user hasn't necessarily been identified, the runtime cannot use the ClaimsIdentity.Name property as a unique identifier for this particular user. Il team ha visto esempi reali in cui ClaimsIdentity.Name restituisce null, restituisce un nome descrittivo (visualizzazione) o restituisce una stringa che non è appropriata per l'uso come identificatore univoco per l'utente.The team has seen real-world examples where ClaimsIdentity.Name returns null, returns a friendly (display) name, or otherwise returns a string that isn't appropriate for use as a unique identifier for the user.

Molte distribuzioni che usano l'autenticazione basata sulle attestazioni usano il servizio di controllo di accesso di Azure (ACS) in particolare.Many of deployments which use claims-based authentication are using Azure Access Control Service (ACS) in particular. ACS consente allo sviluppatore di configurare i singoli provider di identità , ad esempio ADFS, il provider di account Microsoft, i provider OpenID come Yahoo! e così via, e i provider di identità restituiscono identificatori di nome.ACS allows the developer to configure individual identity providers (such as ADFS, the Microsoft Account provider, OpenID providers like Yahoo!, etc.), and the identity providers return name identifiers. Questi identificatori di nome possono contenere informazioni personali, ad esempio un indirizzo di posta elettronica, oppure possono essere resi anonimi come un identificatore personale privato (PPID).These name identifiers may contain Personally Identifiable Information (PII) like an email address, or they could be anonymized like a Private Personal Identifier (PPID). Indipendentemente dalla tupla, ovvero il provider di identità, l'identificatore del nome, funge sufficientemente da token di rilevamento appropriato per un determinato utente mentre Esplora il sito, in modo che il runtime di ASP.NET Web stack possa usare la tupla al posto del nome utente durante la generazione di e convalida di token di campo anti-XSRF.Regardless, the tuple (identity provider, name identifier) sufficiently serves as an appropriate tracking token for a particular user while she is browsing the site, so the ASP.NET Web Stack Runtime can use the tuple in place of the username when generating and validating anti-XSRF field tokens. Gli URI specifici per il provider di identità e l'identificatore del nome sono:The particular URIs for the identity provider and the name identifier are :

  • https://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider
  • http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier

(per altre informazioni, vedere la pagina del documento ACS ).(see this ACS doc page for more info.)

Quando si genera o convalida un token, il runtime dello stack Web ASP.NET in fase di esecuzione tenterà di eseguire l'associazione ai tipi:When generating or validating a token, the ASP.NET Web Stack Runtime will at runtime try binding to the types:

  • Microsoft.IdentityModel.Claims.IClaimsIdentity, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 (per WIF SDK).Microsoft.IdentityModel.Claims.IClaimsIdentity, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 (For the WIF SDK.)
  • System.Security.Claims.ClaimsIdentity (per .NET 4,5).System.Security.Claims.ClaimsIdentity (For .NET 4.5).

Se questi tipi esistono e se il IIIIdentity dell'utente corrente implementa o sottoclassa uno di questi tipi, la funzionalità anti-XSRF utilizzerà la tupla (provider di identità, identificatore nome) al posto del nome utente durante la generazione e la convalida dei token.If these types exist, and if the current user's IIIIdentity implements or subclasses one of these types, the anti-XSRF facility will use the (identity provider, name identifier) tuple in place of the username when generating and validating the tokens. Se non è presente una tupla di questo tipo, la richiesta avrà esito negativo e verrà visualizzato un errore che descrive allo sviluppatore come configurare il sistema anti-XSRF per comprendere il meccanismo di autenticazione basato sulle attestazioni specifico in uso.If no such tuple is present, the request will fail with an error describing to the developer how to configure the anti-XSRF system to understand the particular claims-based authentication mechanism in use. Per ulteriori informazioni, vedere la sezione relativa alla configurazione e all'estendibilità .See the Configuration and extensibility section for more information.

Autenticazione OAuth/OpenIDOAuth / OpenID authentication

Infine, la funzionalità anti-XSRF ha un supporto speciale per le applicazioni che usano l'autenticazione OAuth o OpenID.Finally, the anti-XSRF facility has special support for applications which use OAuth or OpenID authentication. Questo supporto è basato su euristica: se il IIdentity.Name corrente inizia con http://o https://, i confronti del nome utente verranno eseguiti usando un operatore di confronto ordinale anziché l'operatore di confronto OrdinalIgnoreCase predefinito.This support is heuristic-based: if the current IIdentity.Name begins with http:// or https://, then username comparisons will be done using an Ordinal comparer rather than the default OrdinalIgnoreCase comparer.

Configurazione ed estendibilitàConfiguration and extensibility

Occasionalmente, gli sviluppatori possono avere un controllo più rigoroso sui comportamenti di generazione e convalida anti-XSRF.Occasionally, developers may want tighter control over the anti-XSRF generation and validation behaviors. Ad esempio, forse il comportamento predefinito degli helper di MVC e pagine Web per l'aggiunta automatica di cookie HTTP alla risposta è indesiderato e lo sviluppatore potrebbe desiderare di salvare in modo permanente i token altrove.For example, perhaps the MVC and Web Pages helpers' default behavior of automatically adding HTTP cookies to the response is undesirable, and the developer may wish to persist the tokens elsewhere. Sono disponibili due API per semplificare questa operazione:There exist two APIs to assist with this:

AntiForgery.GetTokens(string oldCookieToken, out string newCookieToken, out string formToken);
AntiForgery.Validate(string cookieToken, string formToken);

Il metodo GetTokens accetta come input un token della sessione di verifica della richiesta XSRF esistente (che potrebbe essere null) e produce come output un nuovo token di sessione e un token di sessione di verifica della richiesta XSRF.The GetTokens method takes as input an existing XSRF request verification session token (which may be null) and produces as output a new XSRF request verification session token and field token. I token sono semplicemente stringhe opache senza decorazione; il valore formToken non verrà incluso nel tag di input> di <.The tokens are simply opaque strings with no decoration; the formToken value will for instance not be wrapped in an <input> tag. Il valore di newCookieToken può essere null. in tal caso, il valore oldCookieToken è ancora valido e non è necessario impostare alcun nuovo cookie di risposta.The newCookieToken value may be null; if this occurs, then the oldCookieToken value is still valid and no new response cookie need be set. Il chiamante di GetTokens è responsabile della permanenza dei cookie di risposta necessari o della generazione di eventuali markup necessari; il metodo GetTokens non modifica la risposta come effetto collaterale.The caller of GetTokens is responsible for persisting any necessary response cookies or generating any necessary markup; the GetTokens method itself will not alter the response as a side effect. Il metodo Validate accetta i token di sessione e di campo in ingresso e ne esegue la logica di convalida indicata sopra.The Validate method takes the incoming session and field tokens and runs the aforementioned validation logic over them.

AntiForgeryConfigAntiForgeryConfig

Lo sviluppatore può configurare il sistema anti-XSRF dall'avvio dell'applicazione_.The developer may configure the anti-XSRF system from Application_Start. La configurazione è a livello di codice.Configuration is programmatic. Le proprietà del tipo AntiForgeryConfig statico sono descritte di seguito.The properties of the static AntiForgeryConfig type are described below. Per la maggior parte degli utenti che usano le attestazioni è necessario impostare la proprietà UniqueClaimTypeIdentifier.Most users using claims will want to set the UniqueClaimTypeIdentifier property.

PropertyProperty DescrizioneDescription
AdditionalDataProviderAdditionalDataProvider Un IAntiForgeryAdditionalDataProvider che fornisce dati aggiuntivi durante la generazione di token e utilizza dati aggiuntivi durante la convalida del token.An IAntiForgeryAdditionalDataProvider that provides additional data during token generation and consumes additional data during token validation. Il valore predefinito è null.The default value is null. Per ulteriori informazioni, vedere la sezione IAntiForgeryAdditionalDataProvider .For more information, see the IAntiForgeryAdditionalDataProvider section.
CookieNameCookieName Stringa che fornisce il nome del cookie HTTP usato per archiviare il token di sessione anti-XSRF.A string that provides the name of the HTTP cookie that is used to store the anti-XSRF session token. Se questo valore non è impostato, verrà generato automaticamente un nome in base al percorso virtuale distribuito dell'applicazione.If this value is not set, a name will be automatically generated based on the application's deployed virtual path. Il valore predefinito è null.The default value is null.
RequireSslRequireSsl Valore booleano che determina se è necessario inviare i token anti-XSRF su un canale protetto da SSL.A Boolean that dictates whether the anti-XSRF tokens are required to be submitted over an SSL-secured channel. Se questo valore è true, tutti i cookie generati automaticamente avranno il flag "Secure" impostato e le API anti-XSRF generano se vengono chiamate dall'interno di una richiesta non inviata tramite SSL.If this value is true, any automatically-generated cookies will have the "secure" flag set, and the anti-XSRF APIs will throw if called from within a request that is not submitted via SSL. Il valore predefinito è false.The default value is false.
SuppressIdentityHeuristicChecksSuppressIdentityHeuristicChecks Valore booleano che determina se il sistema anti-XSRF deve disattivare il supporto per le identità basate sulle attestazioni.A Boolean that dictates whether the anti-XSRF system should deactivate its support for claims-based identities. Se questo valore è true, il sistema presuppone che IIdentity.Name sia appropriato per l'uso come identificatore univoco per singolo utente e non tenterà un IClaimsIdentity o ClClaimsIdentity speciale, come descritto nella sezione autenticazione basata su WIF/ACS/attestazioni .If this value is true, the system will assume that IIdentity.Name is appropriate for use as a unique per-user identifier and will not try to special-case IClaimsIdentity or ClClaimsIdentity as described in the WIF / ACS / claims-based authentication section. Il valore predefinito è false.The default value is false.
UniqueClaimTypeIdentifierUniqueClaimTypeIdentifier Stringa che indica il tipo di attestazione appropriato per l'utilizzo come identificatore univoco per utente.A string that indicates which claim type is appropriate for use as a unique per-user identifier. Se questo valore è impostato e l'oggetto IIdentity corrente è basato sulle attestazioni, il sistema tenterà di estrarre un'attestazione del tipo specificato da UniqueClaimTypeIdentifiere il valore corrispondente verrà usato al posto del nome utente dell'utente durante la generazione del token del campo.If this value is set and the current IIdentity is claims-based, the system will attempt to extract a claim of the type specified by UniqueClaimTypeIdentifier, and the corresponding value will be used in place of the user's username when generating the field token. Se il tipo di attestazione non viene trovato, il sistema non riuscirà a eseguire la richiesta.If the claim type is not found, the system will fail the request. Il valore predefinito è null, che indica che il sistema deve usare la tupla (provider di identità, identificatore nome) come descritto in precedenza al posto del nome utente dell'utente.The default value is null, which indicates that the system should use the (identity provider, name identifier) tuple as previously described in place of the user's username.

IAntiForgeryAdditionalDataProviderIAntiForgeryAdditionalDataProvider

Il tipo IAntiForgeryAdditionalDataProvider consente agli sviluppatori di estendere il comportamento del sistema anti-XSRF eseguendo il round trip di dati aggiuntivi in ogni token.The IAntiForgeryAdditionalDataProvider type allows developers to extend the behavior of the anti-XSRF system by round-tripping additional data in each token. Il metodo GetAdditionalData viene chiamato ogni volta che viene generato un token di campo e il valore restituito viene 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 responsabile dell'implementazione può restituire un timestamp, un parametro nonce o qualsiasi altro valore che desidera da questo metodo.An implementer could return a timestamp, a nonce, or any other value she wishes from this method.

Analogamente, il metodo ValidateAdditionalData viene chiamato ogni volta che viene convalidato un token di campo e la stringa "dati aggiuntivi" incorporata all'interno del token viene passata al metodo.Similarly, the ValidateAdditionalData method is called each time a field token is validated, and the "additional data" string that was embedded within the token is passed to the method. La routine di convalida può implementare un timeout (controllando l'ora corrente rispetto al tempo che è stato archiviato al momento della creazione del token), una routine di controllo nonce o qualsiasi altra logica desiderata.The validation routine could implement a timeout (by checking the current time against the time that was stored when the token was created), a nonce checking routine, or any other desired logic.

Decisioni di progettazione e considerazioni sulla sicurezzaDesign decisions and security considerations

Il token di sicurezza che collega i token di sessione e campo è tecnicamente necessario solo quando si tenta di proteggere gli utenti anonimi o non autenticati da attacchi XSRF.The security token that links the session and field tokens is technically only necessary when trying to protect anonymous / unauthenticated users against XSRF attacks. Quando l'utente viene autenticato, il token di autenticazione (presumibilmente inviato sotto forma di cookie) può essere usato come metà di una coppia di token di sincronizzazione.When the user is authenticated, the authentication token itself (presumably submitted in the form of a cookie) could be used as one half of a synchronizer token pair. Tuttavia, esistono scenari validi per la protezione delle pagine di accesso eseguite da utenti non autenticati e la logica anti-XSRF è stata semplificata generando sempre e convalidando il token di sicurezza, anche per gli utenti autenticati.However, there are valid scenarios for protecting login pages hit by unauthenticated users, and the anti-XSRF logic was made simpler by always generating and validating the security token, even for authenticated users. Inoltre, fornisce una protezione aggiuntiva nel caso in cui un token di campo venga mai compromesso da un utente malintenzionato, perché l'impostazione o l'ipotesi di un token di sessione potrebbe essere un altro ostacolo per il superamento dell'autore dell'attacco.It also does provide some additional protection in the event that a field token is ever compromised by an attacker, as setting or guessing the session token would be another hurdle for the attacker to overcome.

Gli sviluppatori devono prestare attenzione quando più applicazioni sono ospitate in un singolo dominio.Developers should use caution when multiple applications are hosted in a single domain. Ad esempio, anche se Example1.cloudapp.NET e example2.cloudapp.NET sono host diversi, esiste una relazione di trust implicita tra tutti gli host nel dominio *. cloudapp.NET .For example, even though example1.cloudapp.net and example2.cloudapp.net are different hosts, there is an implicit trust relationship between all hosts under the *.cloudapp.net domain. Questa relazione di trust implicita consente a host potenzialmente non attendibili di influenzare gli altri cookie (i criteri di origine identici che regolano le richieste AJAX non si applicano necessariamente ai cookie HTTP).This implicit trust relationship allows potentially untrusted hosts to affect each other's cookies (the same-origin policies that govern AJAX requests do not necessarily apply to HTTP cookies). Il runtime di ASP.NET Web stack fornisce alcune attenuazioni nel fatto che il nome utente viene incorporato nel token di campo, quindi anche se un sottodominio dannoso è in grado di sovrascrivere un token di sessione, non sarà in grado di generare un token di campo valido per l'utente.The ASP.NET Web Stack Runtime provides some mitigation in that the username is embedded into the field token, so even if a malicious subdomain is able to overwrite a session token it will be unable to generate a valid field token for the user. Tuttavia, quando sono ospitati in un ambiente di questo tipo, le routine XSRF predefinite non possono ancora difendersi dal Hijack della sessione o dall'accesso XSRF.However, when hosted in such an environment the built-in anti-XSRF routines still cannot defend against session hijacking or login XSRF.

Le routine anti-XSRF attualmente non difendono i clickjacking.The anti-XSRF routines currently do not defend against clickjacking. Le applicazioni che desiderano difendersi da clickjacking possono eseguire questa operazione inviando un'intestazione X-frame-options: SAMEORIGIN a ogni risposta.Applications that wish to defend themselves against clickjacking may easily do so by sending an X-Frame-Options: SAMEORIGIN header with each response. Questa intestazione è supportata da tutti i browser recenti.This header is supported by all recent browsers. Per ulteriori informazioni, vedere il Blog di IE, il Blog SDLe OWASP.For more information, see the IE blog, the SDL blog, and OWASP. Il runtime di ASP.NET Web stack potrebbe in alcune versioni future fare in modo che gli helper XSRF di MVC e le pagine Web consentano di impostare automaticamente questa intestazione in modo che le applicazioni vengano protette automaticamente da questo attacco.The ASP.NET Web Stack Runtime may in some future release make the MVC and Web Pages anti-XSRF helpers automatically set this header so that applications are automatically protected against this attack.

Gli sviluppatori Web devono continuare a garantire che il sito non sia vulnerabile agli attacchi XSS.Web developers should continue to ensure that their site is not vulnerable to XSS attacks. Gli attacchi XSS sono molto potenti e un exploit efficace comporta anche la violazione delle difese di runtime di ASP.NET Web stack contro gli attacchi XSRF.XSS attacks are very powerful, and a successful exploit would also break the ASP.NET Web Stack Runtime defenses against XSRF attacks.

Acknowledgment (Riconoscimento)Acknowledgment

@LeviBroderick, che ha scritto gran parte del codice di sicurezza di ASP.NET, la maggior parte di queste informazioni.@LeviBroderick, who wrote much of the ASP.NET security code the bulk of this information.