it-swarm.dev

Protezione CSRF e app a pagina singola

Sto scrivendo un'app Web client spessa utilizzando Angular.js (app a pagina singola) e mi chiedevo quali sono le migliori pratiche per proteggere l'app utilizzando un token CSRF.

Devo inviare un token CSRF quando l'app viene caricata per la prima volta, quindi riutilizzare quel token su ogni richiesta? Dovrei avere un meccanismo per aggiornare il token? Esistono altre protezioni anziché un token CSRF che avrebbe più senso per un'app a pagina singola?

31
Olivier Lalonde

Bene, ecco come ho finito per implementare CSRF:

Alla prima richiesta, imposta un token CSRF come cookie. Ogni successiva AJAX includono il token CSRF come X-CSRF-Token Intestazione HTTP.

Django ha una buona documentazione su come farlo in modo pulito con jQuery: https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Modifica: un approccio alternativo autorizza le richieste che contengono il X-Requested-With intestazione. Sembra che sia cosa Rails fa . Ma come ha sottolineato @damio sotto, il X-Requested-With è un rischio per la sicurezza, Django e Rails ripristinato torna a non usarlo e forzare un token.

18
Olivier Lalonde

Sei fortunato! Circa 2 settimane fa mi è stata posta la stessa domanda e, dopo un po 'di graffi alla testa, ho pensato a quanto segue. Tieni presente che questo non è ben rivisto tra pari, quindi vedremo come vanno i commenti e le votazioni. Personalmente, penso che sia una buona tecnica.

1. Prima richiesta

Una volta ricevuta la prima richiesta per caricare l'applicazione, generare un identificatore casuale sicuro e archiviarlo in una variabile di sessione sul server, quindi inviarlo al client. Lo incorporerei nella pagina poco prima di </body>.

<script>setToken('<% print SESSION[TOKEN] %>');</script>
</body>

La tua setToken() assegnerebbe il valore del token alla variabile in cui manterresti il ​​token.

2. Richieste successive

Ad ogni richiesta aggiungeresti quel token all'elenco dei parametri, come token=TOKEN, E il servizio lo verificherebbe rispetto a quello memorizzato nella variabile di sessione.

. Aggiornamento del token

Non è davvero obbligatorio, ma è una buona idea aggiornare il token di tanto in tanto, diciamo 15 minuti. Quando ricevi una richiesta dopo la scadenza del token (hai il tempo di scadenza nella variabile di sessione), rispondi normalmente (agisci in modo ottimistico) ma nella risposta dici al client che il vecchio token è scaduto e dovrebbe iniziare a usare il nuovo.

Il client reagisce a ciò dicendo al server che ora conosce il nuovo token, una volta che il server riceve quella richiesta inizia a usare il nuovo token e risponde al client con un messaggio OK, una volta che il client riceve 200 OK Significa entrambi sono sincronizzati e il client inizia a utilizzare il nuovo token.

Nota: Un elemento chiave nel processo è l'utilizzo HTTPS. Non vuoi che un uomo in mezzo annusi il token. Ma ancora una volta, un MitM sarebbe in grado di annusare i cookie e dirottare comunque la sessione.

16
Adi