Come gestire la protezione CSRF in un'applicazione a singola pagina?

4

Attualmente sto costruendo un'applicazione a singola pagina con un front-end JavaScript / HTML. Il front-end effettua chiamate a un'API WEB che è stata scritta in .NET. Attualmente ho una pagina HTML in cui un utente inserisce le proprie credenziali e fa clic su login. Una richiesta AJAX viene quindi inviata all'API WEB che autentica l'utente e restituisce un cookie solo HTTP contenente un token Web Json. Il browser invia quindi questo cookie su ogni richiesta successiva e il controllore lo convalida.

Quanto sopra funziona bene, tuttavia manca la protezione CSRF. Sto cercando di capire il modo migliore di implementarlo. Dalla mia ricerca, sembra che ci siano alcune opzioni.

  1. L'articolo all'indirizzo link suggerisce di estrarre un token da un cookie e quindi inviarlo come intestazione di richiesta. Per fare ciò, dovrei rilasciare il flag Solo HTTP, in modo che il JavaScript possa accedere al cookie. Non penso che questa sia la soluzione migliore, in quanto potrebbe esporre le informazioni sulla sessione se viene rilevata una vulnerabilità XSS. C'è qualcosa che mi manca?

  2. Da qualche altra parte ho letto sull'invio di un cookie separato che conteneva il token CSRF e ne estraeva il valore con JavaScript. Quindi inviando il valore come intestazione personalizzata alle richieste AJAX successive e facendo convalidare l'API WEB in base a tale intestazione. Ho scritto una rapida dimostrazione di applicazione concettuale per questo e ho scoperto che il browser invierà ancora il cookie, il token CSRF è stato consegnato in coda alle richieste future. Questo pone un problema? Potrebbe una pagina con un attacco CSRF in qualche modo sfruttare questo?

  3. Simile a quanto sopra, ma invece di consegnare il token CSRF tramite un cookie, consegnarlo tramite un'intestazione personalizzata e fare in modo che JavaScript lo legga da lì. Sembra che sia il più semplice, ma vedi qualche inconveniente con questo approccio?

Inoltre, è sicuro continuare a utilizzare un singolo token CSRF per l'intera sessione di un utente o dovrebbe essere aggiornato ad ogni richiesta?

    
posta Dave 04.01.2017 - 18:11
fonte

2 risposte

1

È possibile utilizzare le classiche strategie di token CSRF, ma possono richiedere un notevole sforzo da utilizzare nelle applicazioni basate su AJAX e sono disponibili opzioni più semplici per gli endpoint AJAX specifici:

  • Aggiungi un'intestazione extra alle richieste al tuo server come "X-Requested-With: XMLHttpRequest" o "X-Is-Local-XHR: true" e fai in modo che il tuo server richieda l'intestazione sulle richieste autenticate. Gli utenti con vecchie versioni di Flash potrebbero essere vulnerabili (anche se le vecchie versioni di Flash hanno avuto anche vulnerabilità molto peggiori, quindi la scelta se questo è importante per te). Vedi link

  • Verifica che l'intestazione Origin o Referer sia impostata e corrisponda al dominio nell'intestazione Host. L'intestazione Origin viene inviata per tutte le richieste POST da Chrome e Firefox, ma i browser più vecchi potrebbero non includerla. L'intestazione Referer è disabilitata da alcuni utenti per motivi di privacy. La presenza di entrambi con un valore valido è sufficiente per verificare la richiesta.

risposta data 05.01.2017 - 02:17
fonte
1

Questo è un vecchio argomento e ci sono molte discussioni sparse (incluso qui su Security.SE). Tuttavia, invece del suggerimento comune di emulare uno schema di protezione CSRF basato su cookie e post-back, propongo di eliminare completamente i cookie.

Considera l'app a pagina singola come una vera APP e rendila autentica alle API Web utilizzando i metodi standard. Ad esempio, puoi utilizzare token OAuth e richieste senza sessione. (Se OAuth è troppo difficile da configurare, è possibile utilizzare uno schema di token personalizzato.)

Questo risolve anche i problemi con CORS.

    
risposta data 04.01.2017 - 18:37
fonte

Leggi altre domande sui tag