SQL Injection è una tecnica di hacking che colpisce le applicazioni web che producono contenuto dinamico basandosi su query SQL.
In qualità di tester dobbiamo non solo verificare che l’applicazione funzioni correttamente ma anche che sia sicura. Immaginiamo di lavorare per un’azienda che sviluppa software per le banche o che abbia un negozio online. E’ facile comprendere l’importanza di verificare che il codice sviluppato risponda correttamente anche quando sollecitato da malintenzionati.
Supponiamo, ora, di avere un form per l’autenticazione di un utente per effettuare il login in un’area pretetta.
Probabilmente il form di login avrà un campo per inserire la username e la password.
Una volta inseriti i dati, l’utente clicca su un pulsante e i dati vengono inviati all’applicazione la quale usando questi dati costruirà una query per interrogare il database al fine di controllare se le credenziali inserite sono corrette o meno.
Probabilmente il form sarà costruito in questa maniera
[code language=”html”]
<form action=’login.php’ method=’post’>
<label for=’user’>Inserisci UserName:</label>
<input type=’text’ id=’user’ name=’userName’ />
<label for=’pwd’>Inserisci Password:</label>
<input type=’password’ id=’pwd’ name=’passWord’/>
<input type=’submit’ value=’OK’ />
</form>
[/code]
Alla pressione del pulsante OK arriveranno alla pagina login.php le seguenti variabili in post
- userName, con la username inserita dall’utente
- passWord, con la password inserita dall’utente
Queste variabili saranno usate per costruire una query del tipo
[code language=”php”]$sql = "select count(*) from utenti where username=’".$_POST[‘userName’]."’ and password=’".$_POST[‘passWord’]."’";[/code]
Se l’utente ha quindi interito userName=pippo e passWord=paperino la query sarà
[code language=”php”]$sql = "select count(*) from utenti where username=’pippo’ and password=’paperino’;[/code]
La query restituirà quante persone con username pippo e password paperino ci sono nel database.
Fin qui nulla di strano.
Supponiamo, ora, che l’utente inserisca
- userName= pippo
- passWord= ‘
La query eseguita ora sarà
select count(*) from utenti where username=’pippo’ and password=”’
Non notate ancora nulla di strano? Fate attenzione al campo password e alla presenza di tre apici…
Ebbene supponiamo che l’utente ora inserisca
- userName= pippo
- passWord=’ or ‘ 1’=’ 1
select count(*) from utenti where username=’pippo’ and password=” or ‘ 1’=’ 1′
L’esecuzione fornirà il numero di record presenti nella tabella utenti. Abbiamo effettuato un attacco di sql injection.
Questo accade perchè la seconda parte della query e cioè or ‘ 1’=’ 1′ è sempre vera, ed è quella che abbiamo inserito noi nel campo di input. Tutto ciò è stato reso possibile dal primo apice della stringa inserita che ha chiuso prematuramente la prima parte della query (select count(*) from utenti where username=’pippo) permettendoci di inserire una clausula or che è sempre vera. Lo stesso risultato si sarebbe ottenuto usando or ‘ a’=’ a o con qualsiasi altra espressione vera. Ricordatevi di non inserire l’ultimo apice in quanto sarà il codice stesso ad inserirvelo. Lo stesso vettore di attacco si può provare sostituendo i singoli apici con i doppi apici.
Pericolosità dell’SQL Injection
Sfruttando questa vulnerabilità, detta sql injection perchè consiste nell’iniettare codice sql malevolo, potreste loggarvi senza conoscere le credenziali degli utenti. Una volta compromesso il database, i danni che si possono causare possono essere incalcolabili, dalla sottrazione di dati sensibili alla distruzione di record, di tabelle o dell’intero database con comandi tipo “‘; drop nome_della_tabella–”
Si possono anche eseguire dei programmi sul server usando stringhe del tipo
“‘; exec master..xp_cmdshell ‘notepad.exe’–”
In questo caso verrebbe eseguita l’applicazione notepad.exe, ma potrebbero anche essere caricati sul server dei programmi per sniffare il traffico e sottrarre informazioni, il server, quindi, sarebbe completamente compromesso.
Come proteggersi dall’SQL Injection
La SQL injection è una delle tecniche di hacking più pericolose perchè facilmente riproducibili e dagli effetti catastrofici. Per difendersi basta affidarsi ad un principio generale “Non fidarsi mai”. L’errore commesso nell’implementazione presentata prima è proprio quello di fidarsi che i dati inseriti dagli utenti sono sicuri. Per difendersi da attacchi del genere si può iniziare ad esempio escapando gli apici e i doppi apici, e questo può essere fatto usando la direttiva nel file php.ini magic_quotes_gpc, oppure nel codice tramite la funzione addslashes() (in php), si possono controllare che i dati appartengono ad un determinato tipo e si possono lasciar passare solo i dati di ingresso che appartengo ad una whitelist. In pratica si tratta di una lista in cui si elencano solo i caratteri ammessi, tutto quello che non fa parte di questa lista viene eliminato.
Rispetto ad una lista blacklist, che riporta gli attacchi pericolosi, è l’approccio migliore, in quanto in futuro potrebbero nascere nuovi attacchi per cui bisognerebbe poi aggiornare la lista, oltre che elencare tutti i possibili vettori di attacco, cosa che non è assolutamente facile.
Con l’approccio whitelist invece si elenca solo ciò che è valido, è più restrittivo ma è più sicuro.
Inoltre è bene ricordare che i possibili errori dovuti non solo all’sql injection ma più in generale non devono essere presentati all’utente, ma devono essere mascherati tramite messaggi generici al fine di non far conoscere ad evenutali malintenzionati utili informazioni sul tipo di sistema in uso
Alcuni esempi di Sql Injection
Riporto una breve lista di attacchi che possono far scoprire eventuali vulnerabilità di tipo sql injection
'--- ‘ OR ‘ 1’=’ 1
- ” OR ” 1″=” 1
- ‘ /*
- ” /*
- ‘ //
- ” —
- ‘ or 1=1–
- ” or 1=1–
- ‘) or (‘ 1’=’ 1
- ‘) or (1=1
Per maggiori informazioni sull’Sql Injection e sulla sicurezza delle applicazioni web in generale vi consiglio di dare uno sguardo al sito dell’OWASP



