Il modo comune per impedire le richieste CSRF: ogni volta che l'utente carica una pagina che contiene un modulo da POST, all'utente viene rilasciato un token CSRF che dovrebbe essere sconosciuto a siti di terze parti potenzialmente dannosi. Il token viene emesso sia come cookie sia come campo <form>
nascosto. Il client deve autenticare ogni richiesta POST inserendo un token CSRF valido nel corpo della richiesta e presentando un cookie valido.
Supponiamo che l'utente abbia effettuato l'accesso a example.com
e, in un'altra scheda, sfoglia a evil.com
; e evil.com
vuole attaccare example.com/form.html
. Comprendo che evil.com
può inviare una richiesta POST a example.com/form.html
e questo sito interpreterà questa richiesta POST dannosa come una richiesta valida proveniente dall'utente. I token CSRF prevengono questo scenario, perché dovrebbero essere sconosciuti a evil.com
; non può inviare il token corretto con la sua richiesta POST maliocious, quindi il example.com
server rifiuterà quella richiesta.
E qui arriva la parte che non riesco a capire. Il token CSRF viene emesso sia come cookie che come campo modulo nascosto. Per la parte relativa ai cookie, questo è banale: IIUC ogni richiesta a example.com
contiene automaticamente tutti i cookie che provengono da example.com
; quindi, assumendo che su un'altra scheda l'utente abbia effettuato l'accesso a example.com
, la richiesta POST dannosa conterrà il cookie CSRF valido. È corretto?
Per la parte del campo modulo nascosta, questo diventa leggermente più complicato, ma non molto. Evil.com
può emettere un GET XMLHttpRequest a example.com/form.html
e tale richiesta avrà esito positivo, poiché l'utente è connesso a questo sito su un'altra scheda e poiché le richieste GET non sono protette da CSRF. In risposta, evil.com
ottiene example.com/form.html
sorgente HTML, che contiene il <form>
in questione, che a sua volta contiene il campo <input>
nascosto con il token CSRF. Evil.com
ora può analizzare il documento ricevuto, estrarre il token e raggrupparlo con la sua successiva richiesta POST dannosa a example.com/form.html
, il più volte completando un attacco CSRF.
Cosa c'è di sbagliato nel mio ragionamento sopra? Cosa non riesco a capire?