Le applicazioni web che si appoggiano a DBMS (Database Management system) sono molto diffuse ed uno dei principali linguaggi utilizzati per interagire con il db è SQL. In questo articolo parleremo del SQL Injection e di quali accorgimenti adottare per evitare che un attacco informatico violi o distrugga i dati contenuti nel nostro database.
Cos’è l’SQL Injection?
l’SQL Injection è una tecnica diffusissima di hacking che mira a colpire tutti quei siti web che si appoggiano ad un database di tipo SQL.
L’attacco avviene tramite i campi di un form di accesso oppure tramite l’URL della pagina contenente una variabile GET o anche tramite l’uso della libreria cURL per inserire del codice in una query. Queste tecniche di hacking sfruttano la mancata implementazione di controlli sui campi che ricevono input.
I risultati di un attacco di questo tipo possono essere disastrosi in quanto l’intruso può autenticarsi con privilegi di root e visualizzare, o addirittura modificare, i dati contenuti nel db.
Come funziona
Prendiamo per esempio un semplice form:
<form action=’login.php’ method=’post’>
Nome utente: <input type=’text’ name=’user’ />
Password: <input type=’password’ name=’pwd’ />
<input type=’submit’ value=’Accedi’ />
</form>
Il codice PHP che consentirà la convalida dei dati inseriti sarà del tipo:
$query = “SELECT * FROM users WHERE user=’”.$_POST[‘user’].”‘ AND pwd=’”.$_POST[‘pwd’].”‘”;
Se I dati relative al nome utente e alla password sono corretti e trovano riscontro nella tabella che associa le due variabili allora la query fornirà un valore superiore a 0 e si attiverà il codice che consentirà di accedere ai dati richiesti o all’area riservata.
Questo sistema non è sicuro ed ecco perché.
Se proviamo ad inserire nel campo Nome utente un nome qualsiasi (Lupin per esempio) e nel campo “Password” la seguente stringa OR ‘USER‘=’USER‘ andremo ad alterare la query che fornirà come risultato TUTTI gli utenti contenuti nel db e consentirà all’utente Lupin di entrare nel sito anche se non conosce la password.
Cosa è successo? La stringa, in pratica, aggiungendo la condizione USER = USER alla clausola WHERE risulterà sempre vera.
L’esempio su riportato da la possibilità all’attaccante di ottenere informazioni riservate.
Ma esistono query ancora più subdole che potrebbero cancellare tutti i record di una tabella.
Ad esempio la stringa: ‘; DELETE FROM utenti WHERE 1 or username = ‘ andrebbe a creare la seguente query
SELECT * FROM users WHERE user = ‘’; DELETE FROM clienti WHERE 1 or username’’
Questa query (che non va assolutamente eseguita) consentirebbe la cancellazione di tutti i record della tabella clienti.
Come prevenire l’SQL Injection
PHP, per fortuna, ha creato una funzione per prevenire l’SQL Injection : mysql_real_escape_string.
Tramite questa funzione è possibile aggiungere delle sequenze di escape alle variabili GET o POST che andremo ad utilizzare nelle nostre query vanificando, così, eventuali attacchi.
Ad esempio la variabile pwd
$pwd = “‘ OR 1′”;
Verrà “ripulita” in questo modo
$ pwd = mysql_real_escape_string($pwd); (diventando ‘\’ OR 1\’)
Una volta effettuata questa operazione potrà essere inserita nella query senza che arrechi danni.
Non sottovalutare il rischio di SQL Injection. Molti pensano che il proprio sito sia troppo piccolo per interessare qualche malintenzionato. Purtroppo molto spesso questi attacchi non vengono effettuati da un hacker in carne ed ossa ma avvengono tramite tools automatizzati che cercano in modo indiscriminato su tutti gli indirizzi presenti sul web. Tutti i siti sono quindi soggetti ad attacchi a prescindere dalla loro dimensione e/o importanza.