Ho esaminato di recente CSRF . La strategia di mitigazione raccomandata è quella di implementare il Pattern token di sincronizzazione .
Quando guardi i dettagli, viene fuori la domanda con quale frequenza questi token devono essere cambiati. Di nuovo, la raccomandazione generale è che i token per sessione sono sufficienti. Puoi richiedere token per richiesta se hai bisogno di ulteriore sicurezza (o se hai uno scenario in cui i gettoni CSRF che perdono è un problema).
Durante la verifica di come i siti di grandi dimensioni implementano la protezione CSRF, ho dato un'occhiata a github.com. Ciò che mi disturba è che non riesco a capire perché hanno implementato il loro approccio come hanno fatto loro.
Mi viene in mente che utilizzano token per richiesta (anche più, unici per token di moduli). Tuttavia, i token precedenti non vengono invalidati dopo che sono stati utilizzati. Darò un esempio.
Consideriamo la pagina dei profili github: link .
La risposta a una richiesta GET contiene tre moduli con un authenticity_token come parametro di input nascosto. Se ricordo male, github è basato su Rails. Quindi questo si adatta, poiché il nome corrisponde al nome predefinito di meccanismo di protezione di Rails CSRF . Inoltre, i token hanno una lunghezza di 64 byte, che corrisponde alla lunghezza del approccio dei token CSRF mascherati di Rails .
I token sono allegati ai seguenti moduli:
- Token 1: il pulsante Esci
- Token 2: il pulsante Aggiorna profilo
- Token 3: il pulsante Salva profilo di lavoro
Se ricarichi la pagina, i valori di tutti e tre i token cambiano.
Consideriamo un POST successivo che aggiorna il mio profilo.
- Se invio il token previsto 2, l'azione viene eseguita.
- Se invio un token non valido, l'azione non viene eseguita (il server restituisce HTTP 422).
Fin qui tutto bene, ora alle cose che non capisco. L'azione viene anche eseguita, senza errori, quando faccio una delle seguenti richieste:
- Invia un altro token dalla pagina (ad esempio Token 1 o Token 3 dall'alto).
- Invia di nuovo il token 2. Quindi il vecchio token non viene invalidato come utilizzato. Funziona più volte.
- Ricarica la pagina, ma invia uno dei vecchi token.
Quindi immagino si tratti di: Perché github implementa i token per richiesta (anche per modulo), ma non li invalida mai / verifica che essi appartengano all'elemento modulo corretto?
O forse ho torto completamente, e github implementa effettivamente un approccio diverso (come il modello di token crittografato).