Come mantenere un controllo origine / referente per prevenire la CSRF dal blocco degli URL che sono stati digitati?

2

Sto provando a impostare la prevenzione CSRF controllando le intestazioni Origin e Referer e anche bloccando qualsiasi azione se nessuna delle due è impostata.

Tuttavia, se l'URL viene semplicemente digitato o incollato nel browser, tale controllo farà sì che l'azione venga bloccata poiché le intestazioni Origine e Referente non saranno impostate.

Ho pensato forse di assicurarmi che HTTP_HOST sia uguale a SERVER_NAME, ma sembra che possa indebolire il controllo.

Qual è il modo migliore per avere un controllo Origine / Referto sicuro e lasciare che siano gli URL digitati a passare il controllo?

    
posta lindon 30.05.2017 - 01:53
fonte

3 risposte

6

Se si segue la best practice citata spesso di non mutare i dati o lo stato di altre applicazioni sulle richieste HTTP Get, il controllo del referrer sulla richiesta Get diventa un non-problema. Puoi semplicemente utilizzare il controllo referrer su tutti i tuoi post HTTP (o altri metodi se li stai utilizzando).

Lo sfruttamento della CSRF è essenzialmente cieco (salvo gravi errori di configurazione di CORS), quindi basta che le richieste Ricevi sempre solo dati / JSON / HTML / ecc. e non cambiare nulla, stai bene non imporre l'anti-CSRF su di loro. Semplicemente non sono sensibili a questo tipo di attacco.

I messaggi (Puts, ecc.) presumibilmente dovrebbero provenire da un'app conosciuta, quindi dovrebbero avere il referrer corretto a meno che non vengano eliminati da un proxy o da qualche altro software o dispositivo "nel mezzo".

    
risposta data 30.05.2017 - 02:17
fonte
2

What is the best way to have a secure Origin / Referer check and yet let typed in URLs pass the check?

Se stai permettendo che gli URL digitati superino il controllo, creerai inevitabilmente una vulnerabilità CSRF (ovviamente supponendo che gli URL tipizzati non utilizzino i token CSRF e causino cambiamenti di stato sensibili alla sicurezza).

Cioè, un sito dannoso può facilmente omettere il referente e non deve inviare un'intestazione Origin . Ciò rende indistinguibile una richiesta di origine incrociata da un URL digitato. Un modo semplice per rimuovere il referrer dalle richieste di origine incrociata è aggiungendo un meta-header:

<meta name="referrer" content="no-referrer">
<a href="https://yoursite.example/delete_my_account">Click me</a>

In questo esempio, il tuo browser non può sapere se l'utente ha fatto clic sul link o ha digitato manualmente l'URL.

    
risposta data 30.05.2017 - 01:58
fonte
-1

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:

  1. Verifica le intestazioni di origine e referral
  2. 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.

    
risposta data 01.06.2017 - 14:09
fonte

Leggi altre domande sui tag