Domanda:
Qual è il modo corretto per implementare i token di modulo anti-CSRF?
naugtur
2010-11-12 13:58:57 UTC
view on stackexchange narkive permalink

Sono pienamente consapevole di CSRF e ho già implementato alcuni moduli sicuri, ma non sono mai stato soddisfatto dei risultati.

Ho creato token come md5 di nome utente, informazioni sul modulo e un salt e memorizzato in una sessione. Questo ha un problema con la navigazione a schede (può essere risolto mantenendo un array di hash attivi) e con i tempi. Vorrei che i miei hash funzionassero solo per es. 10 minuti, ma come faccio a inserire una variabile relativa al tempo nell'hash?

Qualcuno può indicarmi una buona risorsa che descrive come rendere correttamente la sicurezza CSRF?

Cinque risposte:
#1
+27
Andreas Arnold
2010-11-12 18:37:29 UTC
view on stackexchange narkive permalink

C'è una buona spiegazione su OWASP: OWASP CSRF Prevention Cheat Sheet

In breve si dice che ci sono due modi:

  1. Aggiungi un token casuale a ciascuna sessione utente. Solo se questo token è presente e corretto verranno applicate le modifiche, altrimenti la richiesta dovrà essere rifiutata. È importante che il token venga inviato solo con una richiesta POST, poiché le richieste GET possono far trapelare il token in luoghi diversi (cronologia del browser, file di registro, ecc.).

    È anche possibile generare un token per richiesta, ma questo porta a problemi di usabilità. Ad esempio, il pulsante Indietro non funzionerebbe più correttamente. Ma ovviamente la sicurezza sarebbe aumentata.

    Assicurati anche (per migliorare ancora di più la sicurezza) che il token venga inviato solo tramite TLS, quindi non ci saranno problemi di uomo nel mezzo.

  2. L'altra opzione è usare una sorta di challenge - response (ad esempio CAPTCHA o token una tantum).

La pagina OWASP elenca anche alcune misure che non funzionano. Questi sono

  • Utilizzo di cookie (segreti)
  • Non utilizzo di richieste GET
  • Transazioni in più passaggi
  • Riscrittura URL
La pagina OWASP collegata sopra è stata aggiornata per consigliare i controlli "Verifica della stessa origine con intestazioni standard" oltre ai token descritti.
#2
+25
AviD
2010-11-12 14:35:32 UTC
view on stackexchange narkive permalink

Il modo migliore per creare correttamente la protezione CSRF:

Non.

I framework più comuni hanno questa protezione già incorporata (ASP.NET , Struts, Ruby credo), o ci sono biblioteche esistenti che sono già state controllate. (ad es. CSRFGuard di OWASP).

Un'altra opzione, a seconda del contesto, è imporre la riautenticazione dell'utente, ma solo per operazioni specifiche e sensibili.


Secondo i tuoi commenti, se devi implementarlo da solo, la tua soluzione non è male, ma la semplificherei.
Puoi generare un nonce cripto-casuale (abbastanza lungo ), memorizzalo nella memoria della sessione e modificalo ogni X minuti (memorizzi anche l'ora di scadenza nella sessione). In ogni modulo, includi il nonce in un campo modulo nascosto e confronta quel valore quando il modulo viene pubblicato.
Se il token del modulo corrisponde, sei chiaro. In caso contrario, puoi accettare ad es. anche il token precedente, per gestire i casi limite.

Anche se devo dire che ho visto troppi tentativi falliti di implementarlo da soli, per consigliare davvero questo percorso. È ancora meglio trovare un pacchetto minimo per farlo per te.

OK, questo non risponde del tutto alla domanda. È un sito sulla sicurezza, non sullo sviluppo di applicazioni web. So che dovrei utilizzare le soluzioni esistenti per qualsiasi sicurezza, ma qui mi aspettavo di sapere come viene creata una tale soluzione.
Inoltre, desidero utilizzare la protezione CSRF in un'app che funziona su un piccolo dispositivo incorporato. Conosci qualche framework per questo in bash o perl senza moduli? ;)
Eh, punto giusto sull'incorporato: stai fornendo un'app Web da quello? Nel primo commento, direi che la sicurezza adeguata include "Non reinventare la ruota", ma se ne hai bisogno per incorporata - o solo interessata alla teoria - aggiornerò la mia risposta.
Grazie! Sono contento di averti convinto a rispondermi così facilmente. Le persone spesso diventano davvero cattive quando chiedo cose che non dovrebbero essere reimplementate. ;)
Bene, hai fatto due argomenti convincenti: 1. Voglio capire, e non essere solo una scimmia in codice :), 2. Ho un case edge (incorporato di solito si adatta al conto), e non c'è ancora nessuna ruota lì.
#3
+3
Nasir
2015-01-05 05:26:27 UTC
view on stackexchange narkive permalink

Oltre alla risposta di @Andreas Arnold c'è un'alternativa. Ho implementato il Encrypted Token Pattern da OWasp.

Oltre a prevenire gli attacchi csrf, ha l'ulteriore vantaggio di implementare la sicurezza degli oggetti.

Solo chi è autorizzato a modificare gli oggetti può farlo. Altri non avranno la chiave o il testo cifrato corretto / valido. Di solito crittografo sessionId , timestamp , userId e / o recordId.

timestamp impedisce replayAttacks. sessionid isola solo le modifiche a questa sessione userId isola le modifiche solo a questo utente.Se includi recordId , quindi a costo di un'elaborazione aggiuntiva ottieni maggiore sicurezza.

I timestamp impediscono solo la riproduzione al di fuori di un timeout configurato. Dovresti usare un nonce per quello. Inoltre, un'altra buona proprietà del pattern Encrypted Token è che non richiede lo stato del server (cioè nessuna sessione) e quindi semplifica la scalabilità orizzontale (ad esempio nessuna replica della sessione, nessuna sessione persistente).
#4
-2
Nev Stokes
2010-11-14 00:20:53 UTC
view on stackexchange narkive permalink

Non penso che ci sia molto di sbagliato (anche se potrei sbagliarmi;) includendo un timestamp nel token da sottoporre ad hashing e includendo questo timestamp come campo modulo nascosto - magari codificato in esadecimale come offuscamento di base - puoi quindi controlla la stoltezza al momento della presentazione.

Un timestamp non ha sufficiente entropia. Se l'hai usato come input per un PRF, insieme a una chiave crittografica che non viene mai rivelata a nessun client, potrebbe funzionare, ma è una complessità inutile. Meglio evitare di crearne uno tuo e fare affidamento su un'implementazione ben controllata, come consiglia AviD.
#5
-2
pauld
2013-02-20 01:30:20 UTC
view on stackexchange narkive permalink

Tendo a pensare che la protezione CSRF basata su token possa essere interrotta abbastanza facilmente: un utente malintenzionato deve solo sapere come richiedere una pagina protetta da CSRF, normalmente queste pagine hanno il token come campo nascosto. L'attaccante prende quindi il token dalla pagina (abbastanza banale) e lo usa per costruire un attacco CSRF.

Bene, se stai usando un programma che può interrogare la pagina, per me sei un utente tanto quanto chiunque altro. anti-CSRF serve per impedire l'invio di richieste da un altro sito tramite un normale browser (perché l'utente è loggato e il browser invia le informazioni sulla sessione). Se il tuo codice di attacco può ottenere il contenuto della pagina, non stai più facendo un CSRF. Puoi semplicemente pubblicare qualsiasi cosa.


Questa domanda e risposta è stata tradotta automaticamente dalla lingua inglese. Il contenuto originale è disponibile su stackexchange, che ringraziamo per la licenza cc by-sa 2.0 con cui è distribuito.
Loading...