Qual è lo scopo dell'intestazione / cookie di default in un token anti-contraffazione MVC?

2

Ho letto che il token anti-contraffazione MVC sconfigge gli attacchi CSRF memorizzando i token di sicurezza in un campo modulo e quindi confrontando il valore predefinito dell'intestazione / cookie inviato automaticamente dal browser al valore di campo impostato da MVC su ogni richiesta. Poiché un sito Web dannoso non saprà quale valore fornire al campo che memorizza il token, un attacco CSRF non riesce.

Quindi qual è il punto in cui memorizzare il token nell'header? Non potresti semplicemente memorizzare il token in un campo modulo su ogni richiesta manualmente da Javascript e saltare completamente il confronto?

Questa domanda si applica a me, perché sto creando un singolo segno sullo schema di autenticazione per diverse app eseguite su SignalR, richieste Ajax e moduli ASP.NET. Il mio obiettivo è di evitare gli attacchi CSRF inviando il token di autenticazione in un campo personalizzato per ogni tipo di richiesta: campo nascosto per moduli ASP.NET, parte di req body per AJAX e stringa di query per SignalR (con impostazioni predefinite per disabilitare richieste incrociate), evitando completamente intestazioni e cookie predefiniti.

    
posta Ian 11.05.2017 - 23:55
fonte

2 risposte

3

ASP.NET MVC utilizza una variante del modello di token del sincronizzatore . In un'implementazione tipica, il modello di token syncrhonizer funziona generando un token casuale di grandi dimensioni e conservandolo in due posizioni:

  1. Stato della sessione (sul server o sul client)
  2. In un campo modulo nascosto

Quando viene inviato un modulo, il server controllerà che entrambi i valori corrispondano e falliscano se non lo fanno. Funziona perché un utente malintenzionato non può ottenere il valore del token in anticipo.

ASP.NET MVC modifica leggermente questo pattern non utilizzando lo stato di sessione, ma utilizzando il cookie di sessione. Il token contiene anche alcuni dati aggiuntivi a seconda che si tratti di un token cookie o di un token del campo modulo:

    /* The serialized format of the anti-XSRF token is as follows:
     * Version: 1 byte integer
     * SecurityToken: 16 byte binary blob
     * IsCookieToken: 1 byte Boolean
     * [if IsCookieToken != true]
     *   +- IsClaimsBased: 1 byte Boolean
     *   |  [if IsClaimsBased = true]
     *   |    '- ClaimUid: 32 byte binary blob
     *   |  [if IsClaimsBased = false]
     *   |    '- Username: UTF-8 string with 7-bit integer length prefix
     *   '- AdditionalData: UTF-8 string with 7-bit integer length prefix
     */

Entrambi i token sono crittografati e autenticati e quindi non leggibili dal lato client. Vedi l'implementazione di serializer qui . Data l'anatomia del token sopra puoi vedere che non sono nemmeno identici sul lato client, entrambi crittografano in due diversi ciphertexts e non possono essere convalidati lì.

Probabilmente è possibile modificare il comportamento in modo tale che il cookie non sia necessario memorizzando il lato del server token CSRF nello stato della sessione. Ma hai davvero bisogno di due di loro e hai davvero bisogno di confrontarli per far funzionare la protezione CSRF.

Modifica

Per rispondere più direttamente alla tua domanda originale

What is the purpose of the default header/cookie in an MVC anti-forgery token?

Fornire una soluzione completa che funzioni sempre e per qualsiasi applicazione.

Ha anche un capacità di proteggere le pagine di accesso :

Anonymous authentication

The anti-XSRF system contains special support for anonymous users, where "anonymous" is defined as a user where the IIdentity.IsAuthenticated property returns false. 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. 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. 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. An empty string is used in place of the username for the generation and validation routines described above.

Come per i tuoi commenti, ti stai chiedendo se puoi farlo senza cookie includendo il nome utente cifrato e la data di scadenza in un campo modulo nascosto. La risposta sarebbe dipende .

Tale token potrebbe essere rubato con un attacco XSS mentre un cookie di autenticazione (o cookie token CSRF) contrassegnato con httpOnly non poteva. Ciò renderebbe la tua soluzione vulnerabile nel lasso di tempo della tua scadenza. Se questo è accettabile o meno dipende da te e dal tipo di applicazione. Ad esempio, un'applicazione bancaria netta non tollererebbe alcun tipo di vulnerabilità della CSRF, ma un semplice gioco online potrebbe.

È possibile evitare completamente CSRF se non si utilizzano i cookie per la memorizzazione dei token di autenticazione.

    
risposta data 12.05.2017 - 10:01
fonte
0

Non importa dove mettere il cookie hash del client o altro. Puoi metterlo anche su un campo nascosto di un modulo. Tutto sul lato client sarà comunque accessibile. Questo non è un problema mentre l'utente legittimo è chi sta accedendo a loro.

Il punto come hai detto è di generarlo sul lato server allo stesso tempo e poi riceverlo dal client per verificare se la corrispondenza è ok. In questo modo puoi legittimare la richiesta. Questo è tutto.

Forse, se un utente malintenzionato può rubare un cookie / hash da un client, sarà in grado di eseguire l'attacco CSRF, ma non ha molto senso ... probabilmente se è in grado di rubare da un client ci sarà essere cose più interessanti da rubare come il cookie di sessione per l'accesso o qualcos'altro.

    
risposta data 12.05.2017 - 00:42
fonte

Leggi altre domande sui tag