SQL injection

BackupQuesto articolo è per chi non sa cosa sia la SQL injection.

Con questo termine si identifica una classe di vulnerabilità dei software che consente ad un utente qualsiasi di aggirare i controlli del software e inviare direttamente al server comandi SQL.

Prima della diffusione dei server SQL i dati venivano archiviati e recuperati utilizzando funzioni di libreria del linguaggio di programmazione. Esisteva un comando/funzione del linguaggio per aprire un archivio di dati, uno per cercare un record, un altro per aggiornare i dati, un altro ancora per cancellarli e così via. Con questo sistema era di fatto impossibile portare attacchi tipo SQL injection perché i comandi relativi al trattamento dei dati erano parte del programma. In altre parole, le azioni che avevano come oggetto i dati erano cablate nel programma e non c’era modo di cambiarle se non cambiando il programma (e ricompilarlo).

La diffusione capillare dei server SQL ha cambiato le carte in tavola.

SQL è un linguaggio di programmazione orientato alla gestione dei dati, ma non è il linguaggio con cui è scritto il programma vittima della SQL injection. Per uscire dalla generalizzazione e fare degli esempi, tra i linguaggi potenziali vittime di SQL injection ci sono PHP e ASP, due linguaggi con cui vengono scritti i siti dinamici. Questi linguaggi utilizzano a loro volta il linguaggio SQL per accedere ai dati ed è proprio questo è il punto dolente.

Un linguaggio di programmazione che utilizza SQL ha di fatto un solo comando/funzione per manipolare i dati che è quello che esegue un comando SQL (una query).

Di norma si mette la query SQL in una variabile del linguaggio e la si dà in pasto alla funzione che la fa eseguire al server SQL. Questa variabile può contenere comandi di qualsiasi tipo, dall’estrazione di dati (SELECT), all’aggiunta (INSERT), all’aggiornamento (UPDATE) alla cancellazione (DELETE o DROP).

In questo modo l’accesso ai dati è molto più agile e versatile, ma, mancando una separazione delle funzioni di accesso a livello di linguaggio di programmazione, è anche più facile che un errore di programmazione provochi risultati indesiderati.

La SQL injection si verifica quando i dati in input del programma (ad esempio i dati di un form di una pagina web) non sono opportunamente sanificati, ovvero non vengono effettuati quei controlli destinati ad evitare il verificarsi di comportamenti indesiderati.

Cerco di fare un esempio il più semplice possibile, per comprendere il quale è necessario sapere che in SQL l’apice singolo è un delimitatore di stringa, il punto e virgola indica la fine di un comando e due trattini indicano un commento.

Immaginiamo il più semplice dei form HTML che chiede un nome e lo aggiunge al campo nome di una tabella SQL dati. Se l’utente scrive pippo nel campo, la query risultante sarà:

INSERT INTO dati (nome) VALUES ('pippo');

Ma cosa succede se l’utente scrive un valore con un apice singolo come ad esempio l’acqua?

INSERT INTO dati (nome) VALUES ('l'acqua');

La query andrà in errore di sintassi perché il linguaggio  si trova un delimitatore che non è stato chiuso e non viene eseguita alcuna operazione sui dati.

E se l’utente è particolarmente perfido e scrive aa’);DELETE FROM dati;–?

INSERT INTO dati (nome) VALUES ('aa');DELETE FROM dati;--');

Ricordando che il punto e virgola separa i comandi, la query può essere riscritta in questo modo più chiaro:

INSERT INTO dati (nome) VALUES ('aa');
DELETE FROM dati;
--');

Ovvero prima viene inserito il nome aa, poi vengono cancellati tutti i record della tabella nome e quello che segue è un commento che viene ignorato.

Simpatico, vero?

Ovviamente tutti i linguaggi, siano essi orientati al web o no, che utilizzano il linguaggio SQL hanno funzioni apposite per evitare che questo succeda, ma spesso il programmatore si dimentica di utilizzarle, vuoi perché non pensa che qualcuno possa sfruttare proprio quella vulnerabilità proprio in quella parte di programma, vuoi perché ha fretta e non ha voglia o tempo di mettere troppi controlli perché il capo/committente gli sta urlando alle spalle.

Autore: Luigi Rosa

Consulente IT, sviluppatore, SysAdmin, cazzaro, e, ovviamente, geek.

10 pensieri riguardo “SQL injection”

  1. La stessa classe di problemi si verifica se uno utilizza la concatenazione di stringhe senza controlli per creare comandi da passare al sistema operativo.

    Esempio: chiedo all’utente il nome di un file da mostrare, e lui mi risponde “*; rm -r /*”

    Il programma passa al sistema operativo: “cat *; rm -r /*”

Spazio per un commento