2013-03-26 13 views
6

Ho letto molti articoli sulla protezione CSRF (this is a good one) e varie domande qui su SO, ma nessuno di loro sembra essere sufficientemente informativo da rispondere alla mia domanda.Protezione dei moduli di login e commenti contro CSRF

Sto sviluppando il mio CMS e desidero proteggere i moduli di accesso e di commento. Permetterò agli utenti anonimi di commentare il mio sito web.

Tutti i moduli sul mio sito Web sono protetti tramite token. Conosco già questo approccio, ma il problema è che ha bisogno di una sessione attiva (cioè dopo che l'utente ha effettuato l'accesso). Il problema con i moduli di login e commenti è che sono accessibili a chiunque e non richiedono l'accesso - quale sarebbe la migliore protezione contro CSRF in questo caso?

Sul link sopra, ho letto che potrebbe essere possibile creare una "pre-sessione" quando l'utente tenta di accedere e quindi passare ai soliti metodi anti-CSRF (come l'assegnazione di un token alla sessione dell'utente), ma non ho idea di come ottenere ciò.

L'intestazione del referrer è una soluzione debole, quindi suppongo di non dovermi preoccupare. L'intestazione Origin, è, per quanto ho provato, supportato solo in Google Chrome. Che dire delle intestazioni personalizzate? XMLHTTPRequest sembra una possibilità, tuttavia, ho passato letteralmente più di tre ore su Google a cercare alcune informazioni su come si dovrebbe implementare tale misura di sicurezza sul proprio sito web. Ma anche se potessi usare un'intestazione personalizzata, non lo rende inutile dal momento che le intestazioni HTTP possono essere simulate completamente?

Quindi, la domanda: come dovrei proteggere i miei moduli di login e commenti contro CSRF?

Edit: ecco alcune informazioni aggiuntive dal link che ho fornito in precedenza:

Si consiglia rigorosa convalida Referer per la protezione contro login CSRF perché moduli di login in genere sostengono su HTTPS, in cui l'intestazione Referer è attendibilmente presente per richieste legittime. Se una richiesta di login manca di un'intestazione Referer, il sito deve respingere la richiesta di difesa contro la soppressione dannosa.

e

gettoni di validazione segreto può difendersi login CSRF, ma gli sviluppatori spesso dimentica di attuare la difesa perché, prima di login, c'è nessuna sessione a cui associare il token CSRF. Per utilizzare i token di convalida segreti per la protezione da CSRF di accesso, il sito deve prima creare una "presession" , implementare la protezione CSRF basata su token e quindi la transizione a una sessione reale dopo l'autenticazione corretta.

Non riesco a mettere fine a questo argomento dopo aver letto le citazioni precedenti. Uno di questi menziona l'utilizzo dell'intestazione del referrer, ma non sono abbastanza sicuro se questo aggiunge davvero molto alla sicurezza della webapp.

Modifica 2: Informazioni sull'utilizzo di CAPTCHA?

+0

Questa potrebbe essere una domanda per [Sicurezza SE] (http://security.stackexchange.com/) altrimenti [OWASP] (https://www.owasp.org/) è una buona risorsa per la sicurezza Web. – HamZa

+0

Ma come mai ci sono così tante domande sullo stesso argomento qui su SO? – Onion

+0

Per "completamente" proteggere un'applicazione Web da una certa attaque è troppo ampia (secondo me), altrimenti sarò lieto di vedere una buona risposta che copre questo problema (ed è per questo che ho upvoted :)) – HamZa

risposta

3

Il problema CSRF si riferisce a qualcuno che utilizza le credenziali dell'utente connesso per inviare qualcosa. Questo è molto problematico in quanto un sito dannoso può fare roba come chiunque sia appena sfogliato nel tuo sito. Se parli di moduli che possono essere utilizzati come anonimi, senza effettuare l'accesso, c'è molto meno rischio CSRF in quanto c'è molto meno da guadagnare dalla pubblicazione nel modulo da un altro sito - come chiunque può farlo direttamente anche con le stesse autorizzazioni .

Quindi non capisco perché sia ​​necessario proteggere contro CSRF per moduli non connessi.

Se lo si desidera, un token pre-sessione potrebbe essere tecnicamente simile alla sessione reale, ma solo uno più leggero. Non conterrebbe nient'altro che un token generato.


EDIT: sull'utilizzo del $ _SESSION fornito da PHP per il token pre-sessione, che è phps meccanismo sessione standard. Se vuoi usarlo, allora sì, è tutto.

Tuttavia non sei obbligato a farlo in quel modo, e personalmente non lo farei in quanto consuma memoria del server per tutti i visitatori, e questo non è davvero necessario. Per un meccanismo più efficiente, in pratica è necessario a) un cookie che identifichi l'utente eb) qualcosa memorizzato sul lato server che dice che il cookie è valido (e se necessario, per chi è valido, cioè ip). Per un approccio più leggero si può semplicemente creare un token, memorizzarlo in un cookie e generare qualcosa che corrisponda a quel token nella forma come campo nascosto, e corrispondere a quelli presenti su submit (come spiegato da Devesh). Quest'ultimo impedirebbe l'invio di moduli da un altro sito, il primo impedirebbe anche il caso in cui un sito dannoso effettua una ricerca sul tuo sito e tenta di impostare i cookie anche all'utente finale. Così tre approcci che mi viene in mente:

  • solo evitare che le richieste di immagini da altri siti - usando POST impedisce questo
  • impediscono modulo invia da un altro sito - modulo campo nascosto corrispondenza di un cookie impedisce questo
  • prevenire forma invia da un altro sito che fanno pre-ricerca sul tuo sito - questo avrebbe bisogno di verifica IP, qualcosa memorizzato sul lato server, come ip nel database abbinato al cookie

EDIT2: sui captcha, il loro caso d'uso principale è quello di impedire tentativi di login automatici (forza bruta). Risolvono anche il problema con le richieste CSRF sui moduli di accesso, ma sono eccessivi.Per prevenire attacchi di tipo brute force potrebbero essere necessari in alcuni casi, anche se potrebbe essere più semplice da usare per non degradare troppo l'usabilità. Forse qualcosa come KittenAuth :)

+0

Quindi una "pre-sessione" sarebbe la stessa variabile '$ _SESSION []' che utilizzo dopo che l'utente ha effettuato l'accesso? Come ho capito, questo mi richiederebbe di iniziare una nuova sessione ogni volta che si accede alla pagina di accesso e di assegnargli un token. E DOPO un login riuscito, dovrei distruggere la sessione esistente FIRST, e quindi avviarne una nuova ("full-session", in questo caso), giusto? – Onion

+0

@ user1020567 aggiunto alla risposta – eis

+0

La modifica della sessione non impedisce il CSRF ma impedisce il dirottamento di sessione. L'idea è che un utente possa essere compromesso mentre naviga in pagine non sicure. Quindi, dopo aver effettuato l'accesso, si modifica la sessione in modo che, anche se la sua sessione è stata compromessa, non possono più utilizzare quella sessione dopo l'accesso. –

0

Non è possibile proteggere efficacemente un modulo anonimo contro CSRF. Semplicemente perché l'altro sito può fungere da utente normale.Posso solo creare un sito che fa una richiesta curl al modulo anonimo e memorizzare i cookie e i token nelle variabili. E quindi fai una seconda richiesta per pubblicare il modulo. Lo script non sta falsificando una richiesta, ma sta semplicemente pubblicando automaticamente.

Il punto di CSRF è impedire a uno script/persona di eseguire azioni per conto di un altro utente. Quindi quello sarei io che provo a postare come te. Per evitare che la sessione/cookie con approccio token sia una buona soluzione. Perché non ho modo di ottenere la tua sessione e il tuo token, a meno che il tuo sito non sia difettoso in altre aree. Suggerirei di leggere the OWASP guidelines per avere un'idea di cosa dovresti essere alla ricerca.

Un'altra cosa che dovresti sempre fare è assicurarti che le "azioni" siano sempre con la richiesta POST quindi non posso semplicemente mettere l'immagine sul tuo forum che si collega a 'http://www.yoursite.com/delete.php?id=10'. Se si consente la richiesta GET e si apre la pagina che contiene questa immagine, avrei falsificato una richiesta. Se si consente solo POST non avrebbe alcun risultato.

+0

POST aiuta un po 'ma non così tanto - se c'è un sito dove è possibile l'iniezione javascript, un utente malintenzionato può semplicemente mettere un modulo lì e inviarlo tramite js (in un frame se necessario quindi non si presenterebbe nemmeno). – eis

+0

L'unica volta che uso una richiesta GET sul mio sito è quando voglio visualizzare un particolare post. Ottengo il valore id dall'url, lo sanitizzo e procedo al database, ma in questo caso non ci sono moduli. Sono al sicuro? – Onion

+1

non c'è nulla di male nell'usare 'GET' per visualizzare (ottenere) i dati. Normalmente non dovresti usarlo per i dati ALTER (post/put). –

0

Penso che sia possibile affrontare il tipo di problema CSRF combinando il campo nascosto aggiunto al modulo e allo stesso tempo aggiungere lo stesso valore nei cookie e allegare con la risposta dell'utente. Quando l'utente postback del modulo tenta di far corrispondere il valore del campo nascosto e il valore del cookie proveniente dalla richiesta, se entrambi corrispondono, sei pronto per andare ...

+0

L'approccio cookie non è vulnerabile? Potresti per favore elaborare un po 'di più sull'uso dei cookie per memorizzare il token (io uso solo la sessione attiva sulla mia webapp). – Onion

+0

Puoi vedere qui: http://blog.stevensanderson.com/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/ Lo stesso approccio viene utilizzato da Microsoft per ASP.NET MVC. Non esiste un approccio sicuro al 100%, ma possiamo massimizzare la sicurezza. – Devesh

0

il problema CSRF si riferisce a qualcuno che utilizza le credenziali dell'utente connesso inviare qualcosa. Questo è molto problematico in quanto un sito dannoso può fare roba come chiunque sia appena sfogliato nel tuo sito. Se parli di moduli che possono essere utilizzati come anonimi, senza effettuare l'accesso, c'è molto meno rischio CSRF in quanto c'è molto meno da guadagnare dalla pubblicazione nel modulo da un altro sito - come chiunque può farlo direttamente anche con le stesse autorizzazioni .

Quindi non capisco perché sia ​​necessario proteggere contro CSRF per moduli non connessi.

Se lo si desidera, un token pre-sessione potrebbe essere tecnicamente simile alla sessione reale, ma solo uno più leggero. Non conterrebbe nient'altro che un token generato.

Problemi correlati