Esercizi di ripasso finale in Laboratorio

Giovedì, 12 Gennaio 2006

OBIETTIVI DELLA LEZIONE

In questa lezione ci ritroveremo in laboratorio per completare eventuali esercizi rimasti irrisolti dalle scorse esercitazioni. Dal giorno successivo a quello della lezione, la pagina potrebbe contenere soluzioni ad esercizi proposti precedentemente (soluzioni sviluppate durante la lezione).

Vedremo inoltre alcuni argomenti leggermente più avanzati che non costituiscono materia d'esame.

Introduction to Databases for web developers

Per chi di voi non è (ancora) familiare con i database e il web, o per chi pensa di aver bisogno di materiale ulteriore di approfondimento, il sito introduction to Databases for web developers contiene ottimo materiale di consultazione rapida.

Command Injection Flaws (cenni)

Durante la seconda parte del corso abbiamo visto come sia possibile utilizzare lato client un form HTML per inviare dati inseriti dall'utente ad una CGI lato server.

Nei forms che abbiamo preparato, l'utente è stato libero di inserire ciò che più gli aggradava. Così quando chidedevamo una data, se l'utente avesse immesso una parola i nostri scripts PHP non avrebbero protestato, ma al più avrebbero funzionato in modo scorretto. E se siamo disposti a pagare questo prezzo in termini di utilizzabilità del sito, può anche andare bene così.

Ciò che non abbiamo mai tenuto in considerazione, è invece il caso in cui un malintenzionato volesse deliberatamente sfruttare il fatto che non verifichiamo gli input per manipolare o accedere al nostro sito.

Sono detti command injection flaws (falle per l'iniezione di comando) tutti quegli input (non controllati) che vengono passati come argomenti a programmi esterni o come parte di query SQL a databases. Vediamone un esempio. Torniamo all'esempio della lezione scorsa. Nel file identifica1.php sostituiamo la riga

$query_visualizzazione="SELECT * FROM tab_utenti" .
    " WHERE utente='{$_POST['utente']}' AND password='$md5password'";

con la seguente (differenza evidenziata in giallo):

$query_visualizzazione="SELECT * FROM tab_utenti" .
    " WHERE utente='{$_POST['utente']}' AND password='{$_POST['password']}'";

Sembra che la differenza non sia sostanziale. Proviamo ora ad utilizzare il nuovo script essessione4.php con

utente: ' OR ''='
password: ' OR ''='

Il sito ci riconosce come utente registrato anche se l'unico utente registrato è sassi. L'attaccante è riuscito quindi con una SQL injection (iniezione di codice SQL) a forzare il meccanismo di autenticazione. Come ha fatto? Se sostituiamo gli input utente nella stringa della query verifichiamo facilmente che l'utente è riuscito a modificare la condizione logica su cui si basava la nostra query.

$query_visualizzazione="SELECT * FROM tab_utenti" .
    " WHERE utente='' OR ''='' AND password='' OR ''=''";

L'operazione logica ''='' in SQL è una tautologia (è sempre vera). Problemi come questi sono spesso frequenti nelle applicazioni WEB. Per evitarlo alla radice bisogna porre notevole attenzione e aver studiato bene il PHP (e l'SQL). Molti problemi di vulnerabilità nascono dal fatto che alcuni programmatori utilizzano il taglia/incolla di codice scritto da altri e che non hanno capito a fondo. Una seconda utile abitudine è quella di "disinfettare" (sanitize) l'input dell'utente per evitare che possa inserire caratteri o sequenze problematiche. In questo modo, l'input utente PRIMA di essere utilizzato viene trattato in modo da eliminare tutti i caratteri che non sono ammessi in quel contesto. L'operazione va fatta lato server! Lato client (ad esempioin JavaScript) non è affatto efficace a prevenire questo tipo di problemi (l'utente può sempre evitare i controlli connettendosi al server in telnet sulla porta 80). Esistono numerose librerie di funzioni già pronte allo scopo, ad esempio la collezione OWASP all'indirizzo http://www.owasp.org/software/labs/phpfilters.html.

©2005 Roberto Sassi