Token CSRF non associato alla sessione nell'applicazione Spring

3

Stiamo sviluppando un'applicazione di primavera con Spring Security. Dopo aver eseguito alcuni test della penna, uno dei risultati del test era una vulnerabilità:

Cross-Site Request Forgery Token is not bound to user context.

Abbiamo iniziato a giocare un po 'con i token nella navigazione privata e così, dove eravamo sicuri che le sessioni erano tutte separate e abbiamo notato che l'applicazione accetta i token da una qualsiasi di queste sessioni, cioè possiamo prendere un token in una sessione e semplicemente manipola gli input nascosti di un altro sessone per utilizzare questo token, senza lamentele da parte di Spring quando inviamo il modulo.

Questa mi sembra una vulnerabilità di sicurezza perché (per esempio), scoprendo che l'utente X sta usando la nostra app, qualcuno che gestisce male site.com può anche usare la nostra app e prendere il suo CSRF-Token dal suo / durante la sessione, crea un modulo sul sito maligno example.com che pubblica la nostra app e attira l'utente X in questo modulo.

Ho difficoltà a credere di essere incappato in qualche vulnerabilità di sicurezza sconosciuta in Spring / Spring Security, quindi cosa mi manca? Sto fraintendendo CSRF? Il mio vettore di attacco non è un vettore di attacco realistico?

In termini di configurazioni di sicurezza, abbiamo usato principalmente questa parte della documentazione Spring Security per configurare CSRF.

    
posta flooose 27.02.2018 - 20:03
fonte

2 risposte

5

Quindi, l'abbiamo risolto. Spring Security imposta il CSRF-Token come un cookie, a cui il sito maligno example.com non può accedere perché i siti non possono accedere ai cookie che non provengono dal loro dominio. Al momento dell'invio dei moduli, c'è un campo di input nascosto che ha il token e viene inviato pure. Spring confronta il token nel cookie con il token nell'input nascosto presentato. Se corrispondono, tutto è buono, altrimenti viene restituito 403. Dal momento che malvagio site example.com, non può accedere al token nel cookie, i moduli inviati dal maligno site example.com non possono avere il token CSRF corretto nell'input nascosto (penso che lo spoofing DNS potrebbe dare loro accesso al token in il cookie, ma poi abbiamo un uomo nell'attacco centrale e CSRF)

Il problema con i nostri test sopra era che stavamo cambiando entrambi i token: quello nell'input nascosto e quello nel cookie, che, come detto sopra, un attaccante non può fare, quindi il nostro vettore di attacco era davvero irrealistico.

Inoltre, per questo Spring Security non ha bisogno di associare esplicitamente il token nel cookie a una sessione perché sa che solo il nostro dominio, ovvero la nostra App, può cambiare il token (in realtà penso che ci sia un concetto di "cookie di sessione", ma non è venuto qui), il che significa che finché cambi i token sia nel cookie sia nell'input nascosto a un UUID valido, i token corrisponderanno sul lato server e A Spring Security non interessa. Siamo persino arrivati a utilizzare gli UUID per i token che non sono stati generati da Spring Security, il che significa che Spring Security non li aveva nella loro tokenRepository e che a Spring Security non importava. All'inizio questo ci ha sorpreso un po ', ma suppongo che dal momento che il token nel cookie non è realmente accessibile all'utente malintenzionato, a Spring Security interessa solo se corrispondono.

    
risposta data 28.02.2018 - 21:40
fonte
0

In genere posso parlare con CSRF, ma non con il framework Spring (che non ho usato). Dal momento che non riesco a verificare le tue affermazioni con Spring stessa, prenderò in considerazione le tue affermazioni al valore nominale. Vale a dire:

  1. Puoi recuperare un token CSRF effettuando una chiamata valida utilizzando qualsiasi sessione di tua scelta
  2. Se imponi a qualsiasi altro utente di effettuare una richiesta con il tuo token CSRF, Spring lo accetta come token valido

Supponendo che le tue scoperte siano accurate (ancora una volta non ti sto dubitando, semplicemente non posso verificarlo da solo), questi sono i miei pensieri immediati:

  1. I token CSRF non dovrebbero essere autorizzati ad attraversare sessioni come questa.
  2. Considererei certamente questa vulnerabilità di sicurezza.
  3. Ulteriori dettagli su come Spring convalida i token CSRF sono necessari per decidere se esiste o meno un vettore di attacco realistico qui.

In dettaglio, i token CSRF non dovrebbero assolutamente essere in grado di attraversare le sessioni. Ogni token CSRF deve essere associato alla sessione che lo ha generato e non deve essere un token valido per qualsiasi altra sessione. Come fai notare, consentire ai token di attraversare le sessioni consente a un attaccante di generare token validi prima della mano. Questo può sicuramente essere un problema. Tuttavia, ci sono alcune circostanze che possono mitigare la potenziale minaccia qui:

Molto più della semplice verifica del token

I token sono solo un modo per proteggersi dagli attacchi CSRF. Personalmente, trovo che siano il modo più diretto e affidabile. Tuttavia, non sono l'unico modo. Un'altra opzione è controllare le intestazioni REFERRER e ORIGIN . Se Spring controlla anche le intestazioni REFERRER e ORIGIN, allora è improbabile che questa debolezza nel loro token CSRF sia sfruttabile. Il test che hai effettuato (modificando manualmente il token CSRF tramite gli strumenti del browser) ti lascerà comunque le intestazioni REFERRER e ORIGIN corrette, il che significa che passerai entrambi i controlli CSRF. Tuttavia, non sarebbe possibile per un attaccante riprodurlo. Funziona per te perché eri sulla pagina dell'applicazione vera e hai modificato direttamente la pagina dell'applicazione. Un utente malintenzionato eseguirà un attacco CSRF da un luogo completamente diverso e non potrà forzare le intestazioni REFERRER e ORIGIN. Quindi se Spring è anche controlla le intestazioni REFERRER e ORIGIN, allora stai bene.

La primavera fa entrambe le cose? Non lo so. Perché la primavera farebbe entrambe le cose? Non ne sono sicuro, anche se sarebbe in linea con il concetto di "Difesa in profondità", quindi non sarebbe pazzesco che eseguisse entrambi i test. Se sta facendo entrambe le cose, ovviamente anche una grande debolezza nel token CSRF non ha importanza. Se tuttavia fa entrambe le cose e ignora l'una o l'altra in certe circostanze, allora potrebbe esserci un vettore di attacco se puoi farlo ignorare i controlli dell'intestazione e anche spoofare il token CSRF.

Scadenza del token CSRF

Potrebbe anche esserci una scadenza del token che renderà difficile trasformarlo in un vettore di attacco sfruttabile. In effetti, ha quasi certamente una scadenza simbolica. Come attaccante puoi generare un token CSRF valido, ma se ha una scadenza breve, devi farlo rapidamente davanti a un bersaglio. Supponiamo che tu abbia creato un vettore di attacco CSRF che ha effettivamente elevato il tuo account utente all'amministratore quando un amministratore visualizza una pagina malevola che hai generato. Questo ti farà bene solo se puoi ingannare un amministratore nella visualizzazione della tua pagina di attacco prima che il tuo token scada. A seconda del metodo di consegna e della durata della scadenza del token, questo può essere molto difficile.

Riassumendo: è questa la norma per CSRF? No, in effetti è potenzialmente pericoloso. È sfruttabile? È più difficile rispondere. Come sempre, il diavolo è nei dettagli. Vale la pena scavare di più? Direi di sì.

    
risposta data 27.02.2018 - 20:59
fonte

Leggi altre domande sui tag