Protezione CSRF necessaria per i clienti che non accettano i cookie?

8

Recentemente ho aggiornato un sito Web da Django 1.0 a 1.3. Una delle modifiche introdotte è stata protezione automatica contro gli attacchi CSRF . Per la maggior parte, funziona alla grande, ma ho un problema con i clienti che per qualche motivo non accettano affatto i cookie. Mentre è OK rifiutare a tali client di registrarsi o accedere, dovrebbero comunque poter essere utilizzati, ad es. un modulo di contatto. Django rifiuta tutte le richieste POST che non hanno un cookie CSRF, quindi ho dozzine di errori CSRF ogni giorno che non sono un attacco, ma client legittimi che non accettano i cookie.

Poiché ciò non è accettabile, il mio piano è di modificare il comportamento di Django (attraverso l'estensione del middleware CSRF) in modo tale da consentire alle richieste POST di non avere alcun cookie. Il mio ragionamento dietro questo è che gli attacchi CSRF fanno uso del cookie di sessione per falsificare una richiesta. Tuttavia, non vi è alcun cookie di sessione allegato alla richiesta, quindi in questo caso non è necessaria alcuna protezione contro CSRF.

Quindi, il mio ragionamento suona o sto per strappare un enorme buco di sicurezza nel mio sito web?

    
posta Benjamin Wohlwend 07.11.2011 - 11:42
fonte

4 risposte

6

Django refuses all POST requests

Solo con il meccanismo csrf abilitato. Django emette i cookie csrf in due casi:

  1. Se stai utilizzando il middleware csrf in settings.py . Il middleware si applica a tutte le richieste secondo la specifica WSGI .
  2. Se decori le singole viste con @csrf_protect , senza il middleware

Nel caso di 1, tutte le viste sono protette tramite questo meccanismo e un confronto di {% csrf_token %} (un campo input nel modulo contenente il token csrf) viene confrontato con il cookie inviato.

Hai due opzioni per disabilitarlo, quindi:

  1. Site wide - rimuovi il middleware e le tue richieste POST riprenderanno a funzionare.
  2. Tramite un attento uso di @csrf_exempt puoi scegliere determinate visualizzazioni (url POST) dal meccanismo di protezione csrf.

Quindi non sta usando la protezione csrf come un rischio? Dipende da cosa è la tua richiesta POST. Leggi la la descrizione di csrf di OWASP - fondamentalmente l'idea è che tu costruisci una richiesta e convincere un utente a eseguirla; quando lo fanno, i loro dati vengono modificati in modi che non intendevano accadere. L'idea alla base del confronto dei token è che solo la pagina Web di emissione avrà il token valido, il che significa che una richiesta costruita dannosa dovrebbe essere rifiutata.

Come tale, la risposta a questo è sì, molto probabilmente è un rischio. Per la maggior parte delle applicazioni e dei siti web, desideri questo tipo di protezione.

my plan is to modify Django's behavior (through extension of the CSRF middleware) in such a way, that it lets through POST requests that do not have any cookies at all.

Per i motivi sopra indicati, vorrei sconsigliarlo. Penso che intendiate estendere dal framework esistente (cosa che non dovete fare), ma voglio solo riguardare l'altro caso che altri utenti potrebbero prendere in considerazione, cioè aggiustare il framework django stesso per farlo. In tal caso ... non farlo, perché a meno che ogni sito non abbia il proprio virtualenv estenderai questa vulnerabilità a tutti i siti che usano quel codice, ora e fino a quando non aggiorni la tua installazione di django.

    
risposta data 07.11.2011 - 12:48
fonte
3

Rimuovere completamente la protezione CSRF significa che non ci si può fidare della registrazione delle informazioni per mostrare la vera fonte di una richiesta (per esempio indirizzo IP). Questo potrebbe andar bene nel tuo caso.

Un'alternativa è aggiungere alcune informazioni casuali in un campo nascosto.

Quindi concatena queste informazioni con una stringa segreta, che è nota solo al server. L'hash può essere utilizzato come token CSRF stateless. A seconda del tuo caso d'uso, può essere una buona idea aggiungere un timestamp al campo nascosto e all'hash, quindi controllare che non sia più vecchia di mezz'ora, per esempio.

Per verificare il token, calcola di nuovo l'hash in base al campo nascosto e segreto.

    
risposta data 07.11.2011 - 12:26
fonte
2

Non conosco alcun problema devastante con il tuo piano. Tuttavia, consentitemi di precisare il mio ragionamento e i potenziali rischi, in modo da poter esprimere la vostra opinione sul livello di rischio associato alla rimozione delle difese CSRF.

Vorrei iniziare con una domanda: stai dicendo che il tuo server invierà un'e-mail ogni volta che riceverà una richiesta POST, senza cookie di sessione, senza autenticazione, senza autorizzazione, da parte di chiunque nel mondo? Chiunque nel mondo che ti invia quella richiesta POST farà sì che il server invii un'email, una sola email per richiesta POST? Se è così, questo significa che qualcuno malizioso può far sì che il tuo server invii tonnellate di email, inviando spam al povero destinatario. Se questo è un problema serio o no, non lo so. Dovrai decidere tu stesso in base alla tua tolleranza al rischio.

In generale, ogni volta che una richiesta POST può innescare qualche effetto collaterale sul tuo server, o può far sì che il tuo server intraprenda un'azione sensibile, senza richiedere l'autenticazione, potresti pensare attentamente per assicurarti di non aprirti fino agli attacchi spam / denial-of-service.

Se rimuovi la protezione CSRF, aumenti il rischio. Significa che un utente malintenzionato può creare un annuncio dannoso che, se visualizzato, fa sì che il browser del visualizzatore invii automaticamente una richiesta POST al server, attivando l'effetto collaterale. Questo è un modo molto economico in cui un utente malintenzionato può generare molte richieste POST sul proprio server, in un modo che non offre un modo semplice per bloccare il flusso di richieste dannose (poiché ogni richiesta arriverà da un indirizzo IP diverso) o rintracciare l'attaccante. I token CSRF rendono questo attacco più difficile: ora l'attaccante deve inviare le richieste POST dalla sua stessa macchina e non può sfruttare gli annunci per usare altri come una carezza.

Il rischio aggiunto è piuttosto modesto. Inoltre, se stai utilizzando un sito a basso profilo di basso valore, forse nessuno si preoccuperà di attaccarti, quindi forse non vale la pena preoccuparsene. Volevo solo sottolineare il rischio, anche se risulta essere trascurabile nella tua situazione particolare.

    
risposta data 08.11.2011 - 09:27
fonte
-2

Ho iniziato ad aggiungere un commento sulla risposta di Hendrik Brummermann, ma ho subito esaurito lo spazio, quindi ...

Non capisco perché l'assenza di protezione CSRF possa influire sulla registrazione di un indirizzo IP. E anche se lo facesse, in assenza di una sessione di gestione, quale rilevanza deve avere un indirizzo IP per gestire l'integrità di una transazione?

Inoltre, al fine di evitare replay, il token avrebbe bisogno di variare tra le transazioni - quindi il server avrebbe bisogno di generare nuovi valori per ogni operazione e ricordarli tra le richieste - implicando una sessione - implicando un cookie!

Ciò che manca nella domanda originale sono i dettagli del modello di minaccia - in particolare in assenza di una sessione, che cosa stai cercando di proteggere?

Supponendo che gli attacchi di replay non siano un grosso problema, puoi semplicemente includere sia un valore casuale (R) che l'hash di quel valore casuale + sale (f (R + X)) come campi nascosti. L'incorporamento di un timestamp in R riduce la finestra per qualsiasi attacco di replay (quando aggiungi il macchinario per controllarlo).

Una soluzione senza stato potrebbe essere implementata utilizzando le informazioni fornite in ogni richiesta, ad es. utilizzando l'agente utente e le intestazioni accept e (diciamo) i primi 16 bit dell'indirizzo IP del client E un segreto salt.

Nota che ho regolarmente sottolineato la stupidità nell'uso delle informazioni sull'indirizzo IP per l'autenticazione - e un indirizzo IP del client può cambiare (ad esempio quando si connettono tramite proxy load-balanced) tuttavia IME, l'unica volta in cui i bit più significativi di il cambiamento dell'indirizzo IP si verifica quando il cliente sta deliberatamente cercando di oscurare la propria identità tramite un servizio come TOR - nel qual caso probabilmente non si vogliono comunque i loro POST.

Esistono altri modi per rendere questo identificatore di utente più esclusivo - ad es. proprietà SSL negoziate , il set di cookie corrente (anche se è vuoto!),

Vedi anche panopticlick per ulteriori discussioni sulle impronte digitali dei clienti - ma tieni presente che è probabile che vi siano molte sovrapposizioni tra utenti che non accettano i cookie e gli utenti che non eseguiranno il javascript.

Ovviamente, qualunque sia il dato di riferimento che usi per il controllo, se vuoi implementarlo tramite Django, dovrai eseguire l'override sia del generatore di token che del correttore (CsrfViewMiddleware).

    
risposta data 07.11.2011 - 13:35
fonte

Leggi altre domande sui tag