Sto cercando di capire l'intero problema con CSRF e modi appropriati per prevenirlo. (Risorse che ho letto, compreso e in accordo con: OWASP CSRF Prevenzione CHeat Sheet , Domande su CSRF .)
Da quanto ho capito, la vulnerabilità intorno a CSRF è introdotta dal presupposto che (dal punto di vista del server web) un cookie di sessione valido in una richiesta HTTP in arrivo riflette i desideri di un utente autenticato. Ma tutti i cookie per il dominio di origine sono magicamente collegati alla richiesta dal browser, quindi in realtà tutto il server può dedurre dalla presenza di un cookie di sessione valido in una richiesta è che la richiesta proviene da un browser che ha una sessione autenticata; non può assumere più nulla del codicein esecuzione in quel browser o se riflette realmente i desideri degli utenti. Il modo per evitarlo è includere ulteriori informazioni di autenticazione (il "token CSRF") nella richiesta, trasportate in qualche modo diverso dalla gestione automatica dei cookie del browser. A grandi linee, quindi, il cookie di sessione autentica l'utente / browser e il token CSRF autentica il codice in esecuzione nel browser.
Quindi, in breve, se si utilizza un cookie di sessione per autenticare gli utenti dell'applicazione Web, è inoltre necessario aggiungere un token CSRF a ciascuna risposta e richiedere un token CSRF corrispondente in ciascuna richiesta (mutante). Il token CSRF effettua quindi un ritorno di andata e ritorno dal server al browser al server, dimostrando al server che la pagina che effettua la richiesta è approvata da (generato da, anche) da quel server.
Alla mia domanda, che riguarda il metodo di trasporto specifico utilizzato per quel token CSRF su quel roundtrip.
Sembra comune (ad esempio in AngularJS , Django , Rails ) inviare il token CSRF dal server al client come cookie (ovvero in un'intestazione Set-Cookie), quindi avere JavaScript nel client estrarlo dal cookie e collegarlo come intestazione XSRF-TOKEN separata da rispedire al server.
(Un metodo alternativo è quello raccomandato ad es. Express , in cui il token CSRF generato dal server è incluso nel corpo della risposta tramite l'espansione del modello sul lato server, collegato direttamente al codice / markup che lo restituirà al server, ad es. come input di moduli nascosti. Quell'esempio è un modo più web-1.0 di fare le cose, ma generalizzerebbe bene a un client più pesante di JS.)
Perché è così comune utilizzare Set-Cookie come trasporto a valle per il token CSRF / perché è una buona idea? Immagino che gli autori di tutti questi framework abbiano considerato attentamente le loro opzioni e non abbiano sbagliato. Ma a prima vista, usare i cookie per aggirare ciò che è essenzialmente una limitazione di progettazione sui cookie sembra stupido. Infatti, se si utilizzavano i cookie come trasporto di andata e ritorno (Set-Cookie: intestazione a valle per il server per comunicare al browser il token CSRF e Cookie: intestazione a monte per il browser per restituirlo al server) reintrodurre la vulnerabilità che si stanno cercando di risolvere.
Mi rendo conto che i framework di cui sopra non utilizzano i cookie per l'intero roundtrip per il token CSRF; usano Set-Cookie a valle, poi qualcos'altro (ad es. un'intestazione X-CSRF-Token) a monte, e questo chiude la vulnerabilità. Ma anche usare Set-Cookie come trasporto a valle è potenzialmente fuorviante e pericoloso; il browser ora collegherà il token CSRF a ogni richiesta, comprese le richieste XSRF dannose; nella migliore delle ipotesi, ciò rende la richiesta più grande del necessario e, nel peggiore dei casi, un codice del server ben intenzionato ma mal orientato potrebbe effettivamente tentare di utilizzarlo, il che sarebbe davvero negativo. Inoltre, poiché il destinatario effettivo del token CSRF è Javascript lato client, ciò significa che questo cookie non può essere protetto solo con http.