27/02/2012
Tipi di attacco CSRF
In questo post ho descritto il concetto su cui si basa l'attacco CSRF, mentre in quest'altro post ho provato ad elencare alcuni rimedi da utilizzare per mitigare tale tipologia di attacco.
Adesso vedremo quali sono i diversi tipi di attacco CSRF.
Login CSRF
L'attaccante invia una URL trappola alla vittima, contenente le proprie credenziali di accesso sul sito vulnerabile. In questo modo, appena la vittima effettuerà il login e se il sito lo consente, l'attaccante riuscirà a tenere traccia dei suoi comportamenti (sezioni visitate, link cliccati et similia), semplicemente accedendo al proprio profilo in un secondo momento (vedi YouTube).
Stored CSRF
Il sito vulnerabile consente l'inserimento di codice lato client (Javascript e/o HTML) da parte degli utenti autenticati. Questa in realtà è una vulnerabilità agli attacchi XSS che però può essere utilizzata per creare delle richieste CSRF. Supponiamo che l'attaccante utilizzi i campi di input di un form per iniettare del codice HTML contenente un ulteriore form caratterizzato da diversi campi hidden. Tali campi verranno popolati ad-hoc in modo da creare le giuste variabili da inviare al server tramite HTTP POST.
Ad esempio si potrebbe avere un form del tipo:
<form name="csrf" id="csrf" method="post" action="pagina.php">
<input type="hidden" name="nome" value="Mario" />
<input type="hidden" name="cognome" value="Rossi" />
<input type="hidden" name="telefono" value="06676785" />
</form>
e la seguente immagine "trappola":
<img src="images/immagine.jpg" alt="immagine" onclick="javascript:document.forms['csrf'].submit()" />
L'utente vittima, cliccando sull'immagine, invierebbe i dati al server, i quali verrebbero così processati (si pensi alla classica transazione finanziaria).
Tale tipologia di attacco CSRF è quella che ha un ottimo margine di riuscita, in quanto l'attaccante è certo che l'utente vittima sia effettivamente loggato al sito vulnerabile (altrimenti non potrebbe accedere al form precedentemente forgiato).
Reflected CSRF
L'attacco ha come sorgente "terze parti", ad esempio siti esterni, applicazioni di instant messaging, client di posta et similia. I margini di riuscita sono relativamente bassi, in quanto l'attaccante non può sapere a priori se la vittima è loggata o meno sul sito vulnerabile nel momento in cui viene sferrato l'attacco vero e proprio.
Le metodologie di attacco sono quelle classiche, ovvero creazione di una URL "trappola" oppure l'uso di un form creato ad hoc.
Il form che l'attaccante potrebbe creare è simile a quello visto in precedenza, eccezion fatta per l'attributo action:
<form name="csrf" id="csrf" method="post" action="http://www.sitovulnerabile.it/pagina.php">
<input type="hidden" name="nome" value="Mario" />
<input type="hidden" name="cognome" value="Rossi" />
<input type="hidden" name="telefono" value="06676785" />
</form>
<img src="images/immagine.jpg" alt="immagine" onclick="javascript:document.forms['csrf'].submit()" />
Dai miei esempi si evince come l'HTTP POST offra dei margini di sicurezza migliori rispetto al GET, ma è comunque soggetto ad attacchi CSRF. Per questo, è opportuno utilizzare il token anche se il vostro sito accetta solo dati inviati mediante POST.
Inoltre, nell'ambito degli stored CSRF, se il sito non presenta vulnerabilità XSS (grazie a politiche di input sanitization), il metodo POST associato al controllo del referer HTTP, rappresenta una buona contromisura al CSRF, anche se non ottimale.
Proprio per questo motivo, consiglio di utilizzare i token sempre e comunque.
A presto.
10:00 Scritto da: nazarenolatella in Sicurezza | Link permanente | Commenti (0) | Segnala | Tag: csrf, refrected, login, stored, token, html, form, javascript, xss | OKNOtizie |
Facebook
25/02/2012
Contromisure agli attacchi CSRF
In questo post ho parlato degli attacchi CSRF (Cross Site Request Forgery). Ora vediamo quali sono le possibili contromisure per evitare (o minimizzare) gli effetti nefasti che tale minaccia può provocare.
La semplice definizione del metodo HTTP (GET oppure POST) utilizzato per l'invio del contenuto dei form al server non è sufficiente come contromisura. Infatti, se lato server tali variabili non vengono processate nel modo corretto, una richiesta di tipo POST può essere facilmente trasformata in una richiesta di tipo GET, quindi vulnerabile ai CSRF. Nella fattispecie, pur avendo un form simile al seguente:
<form method="post" action="page.php">
<fieldset>
<legend>Inserisci Contatto</legend>
<input type="text" name="nome" id="nome"/>nome:
<input type="text" name="cognome" id="cognome"/>cognome:
<input type="text" name="telefono" id="telefono"/>telefono:
<input type="submit" name="invia" id="invia" value="Invia"/>
</fieldset>
</form>
dove tutti i campi sono obbligatori, lo si potrebbe facilmente tradurre in questa chiamata HTTP GET:
http://www.nomesito.it/page.php?nome=Mario&cognome=Rossi&telefono=06676754&invia=Invia
Quindi, se un attaccante mandasse un'email contenente la suddetta URL alla vittima, e quest'ultima (che ha una sessione attiva su www.nomesito.it) cliccasse sul collegamento, automaticamente verrebbe salvato nel database un record Mario Rossi 06676754.
Pensate a cosa potrebbe succedere se il sito vulnerabile fosse quello di una banca e la URL trappola portasse l'utente vittima ad effettuare (a sua insaputa) un bonifico di N € sul c/c dell'attaccante...
Per fortuna si può correre ai ripari impostando alcuni meccanismi di sicurezza.
Per prima cosa, occorre scindere lato server (ad esempio nel codice PHP) le chiamate HTTP POST dalle chiamate HTTP GET, utilizzando le giuste variabili globali, ovvero $_POST nel primo caso e $_GET nel secondo.
Se si utilizzano la variabile $_POST ed il filtro sul referer HTTP i margini di sicurezza sono buoni (ma non ottimali), in quanto non potrà funzionare la tecnica enunciata in precedenza, ovvero la trasformazione delle chiamate HTTP POST in chiamate HTTP GET e non verranno accettate richieste provenienti da siti esterni.
Se invece si sceglie il GET come metodo di invio dei dati, oppure non si fa una scelta esplicita e si gestiscono i dati diretti al server mediante la variabile globale $_REQUEST (che non fà alcuna distinzione tra GET e POST), allora è assolutamente necessario procedere in questo modo:
1) si crea un stringa random (token);
2) tale token lo si associa automaticamente ad un campo di input hidden (nascosto);
3) si richiede che il valore del suddetto campo hidden sia uguale a quello del token affinchè si possano salvare i dati nel database.
Per intenderci, si potrebbe utilizzare il seguente codice PHP:
session_start();
$token = sha1(time());
$_SESSION['token'] = $token;
session_write_close();
nella pagina del login, mentre in tutte le altre pagine il codice sarà:
session_start();
$token = $_SESSION['token'];
session_write_close();
if(isset($_REQUEST['invia']))
{
if(isset($_REQUEST['token']) && $_REQUEST['token'] == $token)
{
//invia i dati
}
else
{
die('Non hai i permessi per visualizzare la pagina');
}
}
Il campo di input hidden è così definito:
<input type="hidden" name="token" id="token" value="<?php echo $token ?>"/>
Attraverso questa tecnica l'attaccante non potrà conoscere a priori il valore del token e quindi non sarà in grado di "forgiare" una URL malevola. Inoltre, è consigliabile utilizzare tale procedura anche se si utilizza la variabile $_POST, poichè il token è l'unica contromisura quasi infallibile contro gli attacchi in questione.
Un'altro metodo per mitigare i CSRF consiste nella verifica del campo HTTP_REFERER relativo all'header HTTP.
Però, poichè tale controllo è facilmente aggirabile (basti pensare che alcuni browser, tra i quali Firefox, non inviano per default il referer e che tale campo risulta comunque spoofabile, utilizzando ad esempio cULR), solitamente dedico il suo impiego alle sole pagine "riservate" (ovvero accesibili solo dopo autentica da parte dell'utente) che non prevedono l'invio di dati al server.
Il codice PHP è il seguente:
if($_SERVER['HTTP_REFERER'] != '' && !strstr($_SERVER['HTTP_REFERER'], "http://www.nomesito.it"))
{
die('non hai i permessi per visualizzare la pagina');
}
In soldoni, verifico che il referer HTTP sia vuoto (per non penalizzare utenti legittimi che adoperano un browser che non invia i referer) oppure che contenga il dominio del mio sito, "accertandomi" così che l'utente non provenga da domini "esterni".
Fine del post, fatene buon uso.
A presto.
18:07 Scritto da: nazarenolatella in Sicurezza | Link permanente | Commenti (0) | Segnala | Tag: csrf, web security, cross site request forgery, http post, http get, request, form, input hidden, value | OKNOtizie |
Facebook
13/02/2012
Securimage: captcha PHP semplice ed efficace
Qualunque form HTML che si rispetti, deve garantire delle contromisure valide contro gli spammer bot, avvelendosi di un sistema captcha.
Dopo aver fatto un breve "giro in rete" mi sono imbattuto in questo prodotto (open source).
Diciamo che le operazioni di implementazione e quelle di personalizzazione sono estremamente semplici ed intuitive, basta leggere questa Quickstart Guide per comprendere appieno il funzionamento del tool in questione.
Non vi resta che includere i file PHP richesti, inserire l'apposito campo di input nel vostro form ed il gioco è fatto.
Alla prossima.
10:00 Scritto da: nazarenolatella in Web Editing | Link permanente | Commenti (3) | Segnala | Tag: captcha, form, input, spammer, bot, securimage, image | OKNOtizie |
Facebook

















