Cookie + protezione CSRF basata su sessione

0

Considera il seguente scenario:

1. quando l'utente visita una webapp, server:
a) inizializza la sessione;
b) genera token CSRF;
c) salva token in sessione;
d) salva token sul cookie del cliente tramite Set-Cookie header.
2. su ogni POST server di richiesta confronta il token cookie (che viene automaticamente con Cookie intestazione) con token di sessione e, se non uguale, restituisce 403 .
3. su ogni richiesta ( POST , GET - non importa) il server rigenera il token e lo salva alla sessione e cookie.

In questo modo:

1) esegue token con scadenza rapida, il che rende più difficile per l'attaccante sfruttare la webapp; 2) assicurati che la tabulazione del browser e il pulsante "indietro" non interrompano la sessione. Questo perché ogni volta che il server rigenera il token che riflette nel cookie del client.

Le mie domande sono: posso usare questo approccio nella webapp di produzione o ha delle vulnerabilità?

Grazie.

    
posta Oleg 09.02.2014 - 14:50
fonte

1 risposta

2

È necessario che il token sia inviato nella richiesta all'esterno del meccanismo dei cookie (ad esempio dati POST). Se le sessioni vengono gestite tramite un ID sessione contenuto in un cookie, il tuo approccio non impedisce CSRF.

Nella tua attuale implementazione:

  1. save token to session;
  2. save token to client's cookie via Set-Cookie header.

Questo avrà l'effetto di salvare il token in due posizioni, ma entrambe le posizioni saranno identificate dai valori del cookie.

es. se il token è " 12345678 " verrà salvato in sessione (pseudocodice):

Session["SessionCSRFToken"] = "12345678";

e nei cookie

Cookies.Add("CSRFToken", "12345678");

Tuttavia, al fine di salvare il valore in sessione, il framework dell'applicazione web creerà un cookie per identificare la sessione, in modo da ottenere due cookie impostati:

Set-Cookie: CSRFToken=12345678;
Set-Cookie: SessionID=987654321;

Se un utente accede al tuo sito web a www.foo.com e poi l'utente visita www.evil.com , potrebbe esserci un tag form nascosto incorporato nella pagina di www.evil.com (possibilmente all'interno di un IFrame nascosto) che è automaticamente inviato da JavaScript:

<form method="post" action="https://www.foo.com/Account/DeleteAccount">
</form>

Quando il browser invia automaticamente il modulo, entrambi i cookie verranno inviati insieme alla richiesta ( CSRFToken=12345678 , SessionID=987654321 ) e il token cookie ( CSRFToken ) e il token di sessione ( SessionCSRFToken ) corrisponderanno e l'effetto sarà che l'account dell'utente viene chiuso sul tuo sistema a loro insaputa.

Per impedire ciò, è necessario memorizzare un token CSRF nella pagina stessa (ad esempio all'interno di un input nascosto). In questo modo il tuo modulo può essere inviato solo come segue:

<form method="post" action="/Account/DeleteAccount">
    <input type="hidden" name="CSRFToken" value="12345678" />
</form>

Ora www.evil.com non ha modo di includere l'input nascosto nel proprio codice HTML in quanto non ha modo di conoscere il valore di CSRFToken . Il valore di CSRFToken può essere lo stesso del cookie (il valore della sessione non è più necessario), ma deve essere generato solo una volta la sessione utente (non è necessario rigenerare costantemente il valore).

Per ogni POST devi semplicemente assicurarti che Request.Form["CSRFToken"] == Request.Cookies("CSRFToken") .

    
risposta data 10.02.2014 - 12:39
fonte

Leggi altre domande sui tag