skip to Main Content
info@giuseppegioe.it

SQL INJECTION: come violare un sito internet!

COME PROTEGGERSI DA ATTACCHI SQL INJECTION

Come abbiamo evidenziato, il problema della code injection e della SOL injection in particolare, può portare a scenari devastanti per le applicazioni vulnerabili.

E’ fondamentale che gli sviluppatori abbiano la piena comprensione del fenomeno perché le loro applicazioni siano progettate in modo sicuro da questo punto di vista. Ci sono delle linee guida, delle best practices da adottare in fase di scrittura delle applicazioni che è bene tenere in mente al fine di evitare spiacevoli inconvenienti.

Filtrare l’input utente

La logica di base è che l’input inserito dall’utente (tramite POST o GET) venga opportunamente filtrato prima di essere utilizzato all’interno di query SOL.

Verificare il tipo dati

Quando riceviamo un valore è utile verificare che esso rispetti il tipo di dato atteso. Ad esempio se ci aspettiamo un numero da un form, prima di usare il campo per altri scopi, bisogna verificare che effettivamente sia un tipo numerico aiutandoci, eventualmente, mediante un casting di tipo e forzando, così, a farlo diventare numerico. È chiaro che questo controllo renderebbe inutile un’eventuale tentativo di injection espressa mediante porzione di SOL.

Esempio di casting del tipo:

$interoVerficato = (int) $interoPassato;

Uso di espressioni regolari

Altra tecnica che può tornare utile è quella di usare espressioni regolari per validare i dati in input.

Ricordiamo che un’espressione regolare definisce una funzione che prende in ingresso una stringa, e restituisce un booleano (vero/falso), a seconda che la stringa rispetti o meno un certo pattern. Ad esempio se ci aspettiamo l’inserimento di una partita IVA potremmo, prima di usarla in una query, validarla (almeno dal punto di vista della sintassi) con un’espressione regolare che verifichi il seguente semplice pattern:

“[0-9]{11}$

Anche in questo caso un eventuale tentativo di inie-zione non supererebbe il test imposto dall’espressione regolare interrompendo il flusso di codice destinato ad interagire con il db SQL.

Black liste White list

Spesso si possono definire delle black list e White list per isolare, rispettivamente, caratteri pericolosi e caratteri innocui. Questa tecnica, pur avendo delle controindicazioni, se usata in modo opportuno limita il rischio di iniezioni SQL.

– Escape dei caratteri

Effettuare l’escape dei dati ricevuti. In PHP ad esempio, si può sfruttare la funzione mysqli_realescape_string prima di qualsiasi operazione sul database.

//PHP Script

//prima di usare la variabile faccio un escape

$variabilePost = mysqli_real_escape_string(

$DB_LINK, $variabilePost);

$q uery = “INSERT into citta (nome) VALUES (‘$variabilePost’)”;

$sql = mysqli_query($DB_LINK,$query);

Grazie ,a questa funzione vengono resi innocui i

caratteri potenzialmente pericolosi (apice ecc … )

prima che essi vengano passati alla query.

Limitare i privilegi dell’utente che accede al  database

Le applicazioni per connettersi al database usano un’utenza definita sullo stesso. È buona norma dare privilegi essenziali a questa utenza. Ad esempio se tale utenza non possiede i privilegi necessari a fare un DROP sul database ogni tentativo di injection che tenterà di fare DROP, seppur riesca a passare a causa di controlli inesistenti sull’input, non potrebbe compiere i suoi effetti proprio per i limiti imposti dai permessi definiti sul database.

È dunque buona abitudine far usare alle applicazioni utenze di connessione al database con privilegi ristretti esclusivamente alle operazioni che ricadono nel perimetro dell’applicazione stessa.

Settare un’utenza applicativa con ALL PRIVILEGES sullo schema del db espone a rischi inutili.

– Disattivare la visualizzazione degli errori

Mentre in fase di debug delle applicazioni la visualizzazione degli errori è lasciata attiva per ovvi motivi, quando l’applicativo è in produzione è sempre consigliato disattivare la visualizzazione degli errori  ovvero controllare con cura i messaggi di diagnostica ritornati agli utenti. Difatti, malintenzionati, potrebbero ottenere informazioni preziose analizzando gli errori mostrati dalla nostra applicazione.

Come abbiamo visto in un esempio l’errore volutamente indotto:

The used SELECT statements have a different number of columns ci aiutava a trarre delle conclusioni per inferenza,

tecnica questa utilizzatissima in fase di attacchi SQL injection.

– Limitazione del numero di caratteri

Come abbiamo visto i problemi arrivano da campi di input non controllati. È buona pratica controllare la lunghezza del campo. Esempio: se sappiamo che il nome utente deve essere lungo al massimo 10 caratteri è utile imporre questo limite. Questo da solo renderebbe non possibili iniezioni di query articolate superiori ai 1 O caratteri appunto. In PHP si può usare, per lo scopo, la funzione:

int strlen ( string $string )

al fine di verificare -la lunghezza di una stringa.

– Uso di CAPTCHA

L’utilizzo di un codice CAPTCHA può risultare utile in alcuni contesti al fine di evitare procedure automatizzate di brute force.

– Prepare statements

I maggiori linguaggi offrono supporto alle prepare statements o parameterized statements. Questo concetto introduce notevoli vantaggi in termini di sicurezza al fine di prevenire le injection SQL. In PHP, ad esempio, si può sfruttare l’estensione MySQLi per preparare un template di query da inviare al database.

La query non verrà eseguita immediatamente ma seguirà i seguenti passaggi : verrà prima preparato (con il metodo prepare) un suo template utilizzando dei placeholder (rappresentati dal simbolo ?). Successivamente verrà fatto un binding dei parametri (tramite il metodo bind_param), ovvero un’associazione di una variabile ad un tipo di dato ed al suo placeholder ed infine verrà eseguita la  query sul DBMS tramite un execute

 

Back To Top