CSRF come ti altero info riservate nel sito

Spread the love
Hacking technique csrf
L’attacco di tipo CSRF

Come funziona CSRF

Facciamo un po’ di personaggi e interpreti di questo articolo (CSRF = Cross Site Request Forgery = falsa richiesta tra siti):

  • la vittima: un utente che abitualmente visita e si autentica in
  • un sito che contiene un difetto per il quale si merita l’appellativo di sitovulnerabile.com;
  • un attaccante che è molto bravo e conduce
  • un sitomalevolo.com


Supponiamo che il servizio Web vulnerabile sia quello che consente agli utenti di modificare la loro email utilizzando solo un cookie per l’autenticazione e l’invio di un modulo.

Il sitomalevolo.com sembra innocuo ma ha al suo interno una pagina web con un programma JavaScript che invia di nascosto una richiesta al sitovulnerabile.com con una mail fasulla nel modulo e chiama semplicemente l’URL vulnerabile.

Facciamo un esempio. Il servizio del sitovulnerabile.com consente di modificare l’email dell’utente autenticato attraverso una form HTML: ebbene, l’Attaccante pubblica in sitomalevolo.com un form simile, che invia la stessa informazione al sitovulnerabile.com

<form action="https://sitovulnerabile.com/user/email" method="POST" onLoad="this.submit()">
    <input type="hidden" name="email" value="malicious-email@example.com">
    <input type="hidden" name="user_id" value="12345">
</form>

Requisito 1: l’attacco avrà successo se e solo se l’utente12345 esiste,

Poi l’Attaccante siede sulla riva del fiume ad attendere che passi la vittima, ovvero l’utente che viene in qualche modo indotto a visitare il sitomalevolo.com. Per esempio l’Attaccante adesca la vittima sottoponendola a SPAM e inviandogli una mail “Grossi premi alla Lotteria Web”; all’interno di questa mail mette un link che punta alla form sopra. Inoltre la form è auto inviante quindi la vittima il sito malevolo non lo vede neanche passare (può farlo se apre gli strumenti per sviluppatori AltùShift+I e controlla la scheda Network).

Requisito 2: la vittima dev’essersi precedentemente autenticata sul sito vulnerabile, per poter consegnare al sitovulnerabile.com, quando ritorna sopo l’hop nel sito malevolo, il cookie di sessione.

La richiesta quindi parte dal browser della vittima che attualmente era atterrato sul sito malevolo e invoca il sito vulnerabile chiamando la API di cambio mail e passandogli l’id_utente e il cookie di sessione.

Queste informazioni sono sufficienti a far sì che il sito vulnerabile aggiorni davvero la mail a insaputa dell’utente. Il danno può emergere anche dopo molto tempo, quando l’utente cercherà di entrare nuovamente nel sito vulnerabile (sarebbe meglio dire, a questo punto, sito vulnerato) ma questo gli risponde “User not known”.

Rimedio

Occorre aggiungere una terza informazione che certifica qual è l’origine del dato.

Laravel genera automaticamente un “token” CSRF per ogni sessione utente attiva gestita dall’applicazione. Questo token viene utilizzato per verificare che l’utente autenticato sia la persona che effettua effettivamente le richieste all’applicazione. Poiché questo token è archiviato nella sessione dell’utente e cambia ogni volta che la sessione viene rigenerata, un’applicazione dannosa non è in grado di accedervi.

È possibile accedere al token CSRF della sessione corrente tramite la sessione della richiesta o tramite l’helper csrf_token:

use Illuminate\Http\Request;

Route::get('/token', function (Request $request) {
    $token = $request->session()->token();

    $token = csrf_token();

    // ...
});

L’attaccante non può utilizzare questo metodo perché non gli ritornerebbe alcunché visto che non è autenticato (non ha e non avrà mai il cookie di sessione che invece è nel browser della vittima). E dovrebbe farlo per poter inserire nella form il valore del _csrf.

Ogni volta, infatti, che definisci un modulo HTML “POST”, “PUT”, “PATCH” o “DELETE” nella tua applicazione, dovresti includere un campo CSRF _token nascosto nel modulo in modo che il middleware di protezione CSRF possa convalidare la richiesta. Per comodità, puoi utilizzare la direttiva Blade @csrf per generare il campo di input del token nascosto:

<form method="POST" action="/user/email">
    @csrf

    <!-- Equivalente a... -->
    <input type="hidden" name="_token" value="{{ csrf_token() }}" />
</form>

Il middleware App\Http\Middleware\VerifyCsrfToken, incluso per impostazione predefinita nel gruppo middleware Web, verificherà automaticamente che il token nell’input della richiesta corrisponda al token archiviato nella sessione. Quando questi due token corrispondono, sappiamo che l’utente autenticato è quello che ha avviato la richiesta.

Riferimenti

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.