Come difendere CSRF contro richieste che fingono di non essere browser?

3

So che ci sono una miriade di difese contro gli attacchi CSRF. CSRF, tuttavia, è strettamente una vulnerabilità del browser e qualsiasi richiesta proveniente da un browser diverso è "automaticamente" (e giustamente) consentita.

Ma ... come fai a sapere se una richiesta proviene da un browser o no? Per quanto ne so, l'unico modo è esaminare l'intestazione user-agent .

Questo è tutto a posto, ma, a differenza delle intestazioni Origin e Referer, l'intestazione user-agent può essere modificato a livello di codice :

Note: The User-Agent header is no longer forbidden, as per spec — see forbidden header name list (this was implemented in Firefox 43,) so can now be set in a Fetch Headers object, via XHR setRequestHeader(), etc.

Spiacenti.

C'è un altro modo per determinare se una richiesta proviene da un browser? Oppure, per difendersi dagli attacchi CSRF, sei solo destinato a bloccare anche tutte le richieste di non browser?

    
posta user132711 07.12.2016 - 13:28
fonte

5 risposte

3

Non dovresti aver bisogno di bloccare le richieste non del browser.

Il motivo? Csrf è un attacco a un utente che utilizza un browser. Devono visitare il tuo sito contemporaneamente a un sito dannoso.

Se non ci sono browser, non c'è attacco. Quindi lascia passare i non browser.

Aggiornamento: Dopo Commento di Anders Ora mi rendo conto che la domanda riguardava siti Web che consentono già attraverso richieste di modifica dello stato basate su User Agent. Per favore vedi la sua risposta in quanto riassume bene la situazione in merito a questo.

La mia nuova risposta:

L'approccio migliore è non utilizzare un meccanismo di autenticazione basato su browser per funzioni sensibili. Per qualsiasi accesso al di fuori di un browser, imporre l'accesso utilizzando le chiavi API inviate come intestazioni all'interno della richiesta. I sistemi automatici che utilizzano le API non devono utilizzare un nome utente e un amp; password e ottenere un token di sessione, dovrebbero avere una chiave strong che possa essere allegata ad ogni richiesta.

In questo modo non importa quale sia lo User Agent: identifica i non browser in base al fatto che stanno utilizzando una chiave API inviata in un'intestazione per autenticarsi.

    
risposta data 07.12.2016 - 14:13
fonte
2

Penso che un esempio di attacco CSRF possa aiutare a capire perché si tratta di un attacco basato su browser e perché non è necessario rilevare se il client utilizza o meno un browser.

Diciamo che sei un utente di un sito web www.example.com ed è possibile eliminare il tuo account se fai clic su un link che conduce a www.example.com/delete_account. Cosa succede quando clicchi su quel link? Il tuo browser genererà una richiesta HTTP per quella risorsa (/ delete_account) e includerà tutti i cookie per quel sito in quella richiesta. Pertanto, il server, in base ai cookie inclusi, saprà che sei tu e che desideri eliminare il tuo account e lo farai.

Il problema è che qualcuno potrebbe creare una pagina dannosa e includere un iframe con l'attributo src che punta a www.example.com/delete_account. Se visiti quel sito dannoso e sei collegato a www.example.com, il tuo browser proverà a eseguire il rendering dell'iframe inviando una richiesta a www.example.com/delete_account e includerà anche i cookie in tale richiesta. In questo modo, in caso di mancata protezione CSRF, il tuo account verrebbe eliminato su example.com.

Ciò significa che CSRF si verifica se per esempio ti fidi di un'azione degli utenti solo in base ai cookie che manda, e il problema è che i browser inviano automaticamente i cookie. Ecco perché la protezione CSRF è importante.

Posso farti eseguire la stessa richiesta a www.example.com/delete_account utilizzando un browser diverso? Questo in realtà non avrebbe senso. Potrei provare a convincerti a copiare incollare la richiesta in Burp, e in aggiunta dovresti copiare manualmente incollare i cookie nella richiesta ... e in realtà non ha senso :) Il modo migliore per capire è non pensare come la protezione funzionerebbe, ma a pensare a come avrebbe funzionato l'attacco.

    
risposta data 07.12.2016 - 14:46
fonte
2

Se ti ho letto bene, stai considerando uno scenario in cui il sito http://completely.not.evil.com ha uno script come questo incorporato:

var req = new XMLHttpRequest();
req.setRequestHeader("User-Agent", "Totally not a browser");
req.open("POST", "http://example.com/delete_account");
req.send();

Questo attacco fallirà. Tutte le altre risposte dicono cose valide su CSRF, ma nessuno di loro menziona il pezzo mancante del puzzle che spiega perché l'attaccante non può ingannare il browser delle vittime per inviare una richiesta con un agente utente modificato. E quel pezzo è CORS .

L'impostazione dell'intestazione User-Agent farà in modo che il browser esegua una richiesta diOPTIONS pre-volo al server per vedere se è consentita. A meno che non configuri in modo specifico il tuo server per consentire ciò - che ti sparerebbe al piede - non risponderà positivamente. Il browser non invierà quindi la richiesta POST che avrebbe effettivamente eseguito l'azione dannosa.

Quindi, in conclusione, l'autore dell'attacco non può modificare con successo l'intestazione User-Agent a meno che non le permetta di farlo.

    
risposta data 08.12.2016 - 00:19
fonte
1

In breve: non devi preoccuparti di CSRF e di non browser.

Per un attacco CSRF per avere successo, il tuo sito web deve ricevere una richiesta con tutte le intestazioni e i cookie di un cliente, e non essere in grado di dire se il tuo sito o una terza parte ha fatto la richiesta.

Per un utente che non effettua il browser attacca un utente, dovrebbe indovinare (o possedere) tutti i cookie e le intestazioni utilizzati dal sito, trasmettendo tutte le informazioni della sessione come se l'utente stesse effettuando la connessione.

    
risposta data 07.12.2016 - 15:16
fonte
1

Non devi preoccuparti del fatto che l'agente utente sia stato modificato perché

CSRF non proviene da un utente malintenzionato

Le richieste forgiate coinvolte in un attacco CSRF non vengono emesse dall'attaccante. Vengono emessi dal browser utente legittimo . Questo è il punto centrale. L'hacker sta violando la legittima sessione dell'utente legittimo (ecco perché l'attacco viene talvolta chiamato sessione di guida ). L'autore dell'attacco ha semplicemente convinto l'utente a inviare la richiesta in qualche modo (ad esempio facendo clic su un collegamento o aprendo un'e-mail accuratamente predisposta); in realtà non è coinvolto nel traffico o nella connessione di rete.

L'idea che l'utente malintenzionato forgi un'intestazione user-agent e inviare la richiesta non si adatta affatto a questo scenario. Sicuramente ci sono altri attacchi che possono essere emessi direttamente da un hacker, usando uno strumento di hacking di sua scelta, ma nessuno di questi attacchi è CSRF, per definizione .

    
risposta data 07.12.2016 - 20:31
fonte

Leggi altre domande sui tag