Esiste una valida tecnica di prevenzione lato server contro CSRF supportato da PHP?

4

Inizierò col dire: sono solo un appassionato di sicurezza informatica, non un esperto. Quindi, affermerò quello che penso di conoscere fino ad ora, per favore sentiti libero di correggermi in qualsiasi momento.

Attraverso le mie letture, ho imparato a conoscere:

  • L'esistenza di CSRF
  • Le basi dietro di esso, per entrambe le richieste GET e POST
  • Tecniche di mitigazione e Referer
  • Come è possibile recuperare il token se il sito web di destinazione ospita una vulnerabilità XSS
  • Il fatto che il referer sia passato in chiaro attraverso le intestazioni HTTP e potrebbe quindi essere falsificato
  • cURL utilizzato per caricare prima la pagina, ottenere il token e usarlo per inviare i dati POST e ottenere i contenuti post-auth della pagina

Quindi la mia domanda è la seguente: se qualcuno usa uno script PHP che carica la pagina che ospita il modulo POST, ottiene il token generato casualmente e invia i dati POST con un'intestazione "Referer" personalizzata che corrisponde al sito web di destinazione, è c'è qualcosa che posso fare sul mio server per mitigare questo?

    
posta MadWard 23.05.2016 - 17:06
fonte

2 risposte

3

Penso che tu abbia frainteso il modo in cui funziona un attacco CSRF e perché i token CSRF proteggono contro di loro. Quindi, iniziamo con come funziona.

L'attaccante inganna la vittima a visitare http://evil.com che contiene un modulo che esegue automaticamente un POST a http://bank.com/transfer?to=evilHacker&amount=1000000 . Se la vittima è già registrata nella sua banca, il cookie con l'ID di sessione verrà inviato come al solito dal browser e non è possibile per il server bancario sapere che la vittima non intende effettivamente trasferire i soldi. Tieni presente che questo si basa sul browser che invia il cookie con l'ID di sessione a bank.com .

Quindi, come può aiutare un token CSRF? Se bank.com controlla sempre che un token casuale unico per quella sessione sia presente nella richiesta, evil.com non può falsificare la richiesta poiché il malvagio hacker che esegue quel sito non sa quale sia il token.

Il controllo referer funziona in modo simile. La richiesta fatta dal browser dal sito evil.com avrebbe evil.com e non bank.com come referente. I browser non consentono la modifica dell'intestazione del referer, quindi l'autore dell'attacco non può falsificarlo.

Quindi che mi dici della tua linea di attacco: chiedere al malintenzionato di richiedere al sito uno script PHP sul suo server per ottenere il token CSRF? Questo non funzionerà, perché l'utente malintenzionato non riceverà il token CSRF delle vittime. Il token è unico per la sessione e quindi il cookie con l'ID di sessione. Ma gli aggressori non sanno quale ID di sessione ha la vittima, quindi non può includerlo nella richiesta.

Notare la differenza rispetto al primo scenario, in cui il browser includeva il cookie. Questo non può accadere sul server.

    
risposta data 23.05.2016 - 17:33
fonte
0

La risposta di Anders affronta la domanda, ma offre solo la soluzione per archiviare una copia del token nella sessione. Sarebbe anche possibile archiviare il lato client del token finché è protetto adeguatamente dagli attacchi di replay, ma questo ha una significativa sovrapposizione con il problema del dirottamento di sessione ....

if ($_REQUEST['token']) {
   if (validate($_REQUEST['token'], $_COOKIE['ctoken'])) {
     // do the protected thing....
   } else {
     // handle exception
   }
}
$token=sha1(openssl_random_pseudo_bytes(40)) . ":" . time();
$client_stored_token=encrypt($token, create_key);
set_cookie('ctoken',$client_stored_token);

function validate($token, $client_stored_token) 
{
    $client_token=decrypt($client_stored_token, create_key());
    @list($rand_bytes, $timestamp)=explode(':', $client_token);
    if ($rand_bytes==$token && time()-$timestamp<MAX_THRESHOLD) {
       return true;
    } 
    return false;
}
function create_key()
{
   return sha1($_SERVER['HTTP_USER_AGENT'] 
      .(int)(ip2long($_SERVER['REMOTE_ADDR'])/65536)
      .SOME_STATIC_SALT);
}

(potrebbe anche essere possibile propagare il token tramite window.name ma è necessario un po 'di riflessione).

Anders ha notato che:

Browsers do not allow modification of the referer header, so the attacker can't forge that.

Sfortunatamente ci sono un sacco di problemi con l'intestazione del referer in vari browser - verrai sbloccato se ti affidi a questo.

The fact that the referer is passed in clear text through HTTP headers and could thus be spoofed

Anche i più sofisticati meccanismi CSRF e di protezione delle sessioni vengono facilmente sconfitti da un MITM su una connessione HTTP. Ecco perché utilizziamo HTTPS.

    
risposta data 23.06.2016 - 13:45
fonte

Leggi altre domande sui tag