Il falsificatore di richieste intersito (noto anche come attacchi CSRF o XSRF) è un attacco che consente agli aggressori di eseguire azioni indesiderate su un'applicazione Web in cui un utente è attualmente autenticato. L'attacco è possibile quando l'applicazione mirata non convalida correttamente l'origine della richiesta e fa affidamento esclusivamente sull'esistenza di una sessione valida tra il browser della vittima e il server dell'applicazione.
Nello scenario più comune di un attacco CSRF, un utente connesso accederà a una pagina Web aggiuntiva fornita dall'hacker in un'altra scheda del browser. Questa pagina verrà immediatamente indirizzata a una funzione sensibile all'interno dell'applicazione, che è ancora aperta nell'altra scheda, inviando una richiesta appositamente predisposta. Poiché la richiesta viene inviata dallo stesso browser, l'applicazione vulnerabile accetterà la richiesta ed eseguirà l'azione.
LacorrettaprotezioneCSRFsibasasullaprevenzionechegliaggressoripossanocreareunarichiestagranularediazioniinunsistema.Unasoluzioneaquestotipodiattaccoconsistenell'implementaretokencasualiunivociperleformesensibili.Perogniinviodimoduli,iltokendeveessereconvalidatosullatoserver.
Comenotaamargine,questitokendovrebberosempreessereinviatiutilizzandoilmetodoPOST.Disolitovengonoforniticomecampomodulonascosto.
EccounesempiodiimplementazioneCSRFperPHP:
- GenerazionediuntokenCSRFsicuroinPHP
functiongenerateCSRFKey($key){$token=base64_encode(openssl_random_pseudo_bytes(16));$_SESSION['csrf_'.$key]=$token;return$token;}
Potrestiesseretentatodiusarerand()ouniqid()maentrambispecificanoesplicitamentechequestefunzioninondevonoessereutilizzatepergeneraretokensicuri!Anchebase64_encode()èusatosoloperassicurarsicheilvalorenoninfrangealcuncodiceHTML.
Il controllo di un token inviato è valido:
function checkCSRFKey($key, $value) {
if (!isset($_SESSION['csrf_' . $key]))
return false;
if (!$value)
return false;
if ($_SESSION['csrf_' . $key] !== $value)
return false;
unset($_SESSION['csrf_' . $key]);
return true;
}
Il codice sopra può essere usato per aggiungere un token univoco a qualsiasi modulo usando:
" name="token">
- Il codice da verificare sul lato server se il token fornito è valido:
$token = $_POST['token'];
if (checkCSRFKey('settings', $token)) {
// Handle error
}