Penso che valga la pena dedicare del tempo per chiedere perché si sta utilizzando un controllo origine e referente per abilitare la convalida CSRF.
Il modo più sicuro per eseguire un controllo CSRF è utilizzando i cookie (beh, la sessione dell'utente, in realtà) per memorizzare un token che deve tornare con la richiesta finale. I cookie rendono l'intero processo molto semplice e molto meno soggetto a errori (per il tuo utente finale). L'unica volta in cui dovresti avere fare l'origine e la convalida CSRF basata sul referrer è quando la memorizzazione della chiave nella sessione dell'utente non è possibile. Tuttavia, se sei preoccupato per l'utente che digita gli URL direttamente nel browser, significa che l'utente finale sta operando dal browser, il che significa che hai accesso specifico ai cookie / sessioni. Quindi sospetto che la vera risposta alla tua domanda sia quella di adattare le tue procedure CSRF all'uso dei cookie, non al referrer / all'origine.
Tuttavia, per rispondere alla tua domanda, la risposta è che no, non puoi fare nulla per consentire all'utente di digitare l'URL direttamente nel browser e ottenere comunque l'accesso a qualsiasi risorsa / azione che la tua configurazione CSRF sta proteggendo. Tranne che utilizzando i cookie, non c'è modo di distinguere tra un utente che digita direttamente un URL e un attacco CSRF dannoso.
Modificato per aggiungere ulteriori dettagli:
Il token CSRF che sto descrivendo si chiama token Synchronizer su questo pagina . L'idea è di pre-calcolare un segreto, memorizzarlo nella sessione dell'utente (che è il motivo per cui i cookie sono coinvolti), includerlo nel modulo che verrà inviato (ma non inserirlo in un cookie reale), e quindi verificare che il token CSRF abbia visualizzato il modulo e corrisponda a ciò che è stato memorizzato nella sessione. Il motivo per cui funziona è che l'azione non è consentita senza il token e il token non viene fornito finché l'utente non visita effettivamente il modulo per eseguire l'azione. Per ulteriore sicurezza, rigenererai anche il token per ogni invio di moduli. Di conseguenza, un utente malintenzionato non può completare in modo silenzioso un'azione nello "sfondo" perché tutte le azioni possono essere completate solo se l'utente visita prima la pagina che contiene il modulo e quindi invia il modulo effettivo.
La pagina a cui fai riferimento in OWASP suggerisce di utilizzare un paradigma di doppia sicurezza per la protezione dagli attacchi CSRF:
- Verifica le intestazioni di origine e referral
- Utilizza un token CSRF
Corretta applicazione dei dettami di difesa in profondità che adottano tutte le misure di sicurezza necessarie, motivo per cui suggeriscono l'utilizzo di entrambi i metodi per la protezione da CSRF. A volte però, la realtà richiede un compromesso, quindi vale la pena menzionare tutti i pro e i contro di entrambi / entrambi. Soprattutto, se fatto correttamente, entrambi i metodi ti proteggeranno contro tutti i vettori di attacco CSRF attualmente noti. Ovviamente è qui che entra in gioco la difesa in profondità, poiché avere una maggiore sicurezza (cioè implementare entrambe le misure di difesa) aumenta potenzialmente le possibilità di mitigare attacchi futuri che non sono ancora stati escogitati.
Nonostante questo, ogni framework con cui ho mai lavorato usa solo la protezione dei token CSRF out of the box (per quanto ne so). Questo include Code Igniter, Laravel, Django e Ruby on Rails. Nel caso di Django e Ruby on Rails faccio affidamento sulla loro documentazione per verificare questo fatto (è possibile che abbiano lasciato alcuni dettagli fuori), ma per codeigniter e laravel ho ricontrollato il codice sorgente stesso per assicurarsi che non fossi t sbagliato. Quindi, in realtà, è comune sul Web abilitare la protezione CSRF utilizzando solo token CSRF. Che questa sia o meno una buona idea per te dipende dal livello di comfort del bilanciamento tra sicurezza e usabilità. Tuttavia, certamente non è assurdo usare solo token CSRF per eseguire la mitigazione CSRF: molti sistemi software famosi fanno esattamente questo.
Mi viene in mente di porre un'altra domanda: perché il tuo sistema CSRF impedisce agli utenti di digitare un indirizzo? Se un utente digita semplicemente un indirizzo nella propria barra degli indirizzi per visitare la propria pagina, esegue una richiesta HTTP / GET e le richieste GET non dovrebbero essere soggette alla protezione CSRF poiché il server non dovrebbe mai intraprendere azioni in risposta a una richiesta GET. Quindi, in realtà, potrebbe esserci anche una soluzione più semplice al tuo enigma: assicurati di non intraprendere azioni in risposta a una richiesta GET e quindi di disattivare la protezione CSRF su tutte le richieste GET. Quindi, gli utenti saranno in grado di digitare in un browser tutti gli URL che desiderano.