SQL injection: come funziona, come proteggersi Gli scarsi controlli nell’interfaccia SQL con il data base consentono attacchi molto pericolosi. M.R.A. Bozzetti, OAI founder In questa stessa rubrica, circa un anno fa, nell’articolo I dieci principali errori nella programmazione che causano vulnerabilità , avevo commentato i principali errori di programmazione che generano vulnerabilità negli applicativi e che sono i principali mezzi che consentono attacchi. Al secondo posto si ponevano gli scarsi controlli nell’interazione con banche dati tramite SQL, Structured Query Language, che consentono attacchi tipo SQL injection, una tecnica che sfrutta gli scarsi controlli in un’interrogazione SQL a una banca dati. Molti dei recenti attacchi, come quello a Sony, hanno usato questa tecnica, come riferito in precedenti articoli di questa rubrica. Per questo motivo ho ritenuto opportuno chiarire cosa sia, come funziona, e come sia possibile evitare attacchi di questi genere; pur non entrando in dettagli, questo articolo è più tecnico rispetto al consueto taglio informativo e manageriale della rubrica OAI. Per comprendere a grandi linee come funziona un attacco con SQL injection, per brevità indicato con SQLIA (SQL Injection Attack), è necessario comprendere il contesto nel quale opera. SQL è un linguaggio di interrogazione di una banca dati di tipo relazionale. È divenuto standard ANSI e ISO, ed è così diffuso e consolidato che alcuni database hanno questo acronimo nel loro nome: si pensi a MySQL e a Microsoft SQL Server. In un database relazionale i dati sono rappresentati come relazioni in tabelle e manipolati con gli operatori dell’algebra relazionale: operatori di confronto, aritmetici, condizionali e logici. SQL è un linguaggio dichiarativo: le istruzioni SQL consentono di leggere, modificare, cancellare i dati e di espletare funzioni gestio- 88 office automation luglio-agosto 2011 nali e amministrative. Esse sono strutturate nei seguenti sottosistemi: • DDL, Data Definition Language, per creare, cancellare e modificare la struttura di un database; • DML, Data Manipulation Language, per inserire, cancellare e modificare i dati; tipiche istruzioni sono <select>, <insert>, <update>, <delete>; • DCL Data Control Language, per gestire gli utenti e i loro diritti; • QL, Query Language, permette di interrogare il database, cioè di leggere i dati; • DMCL, Device Media Control Language, per gestire lo storage dove sono memorizzati i database. L’utilizzo delle istruzioni SQL con i relativi operatori può essere effettuata direttamente dall’amministratore del database con interfaccia a singolo comando o di tipo grafico (GUI), oppure tramite linguaggi di programmazione o script. Per sviluppare pagine web dinamiche esistono vari strumenti e linguaggi, i più diffusi sono PHP (Hypertext Preprocessor) in ambito Linux e ASP (Active Server Pages: sono pagine web che oltre al codice HTML contengono script che vengono eseguiti dal web server Microsoft IIS) in ambito Microsoft. I vari linguaggi di programmazione utilizzano delle API, Appication Program Interface, per inserire le istruzioni SQL e interfacciarsi ai database. Diverse possono essere le modalità di attacco SQLIA a un’applicazione web, ma tutte si basano sulla mancanza, totale o parziale, di controlli sui dati di input. Si consideri il semplice esempio (derivato da Wikipedia) di un form di login da un browser a una applicazione web tramite verifica dell’identificativo dell’utente e la sua password tramite uno script PHP; questi dati sono archiviati in un database My SQL. Lo script di autenticazione dell’utente è costituito da due file: uno è il form di login in html (form.html in fig.1), l’altro (login.php in fig. 2) verifica che i dati inseriti dall’utente con il form si trovino corri- <form action='login.php' method='post'> Username: <input type='text' name='user' /> Password: <input type='password' name='pwd' /> <input type='submit' value='Login' /> </form> Fig. 1 - Istruzioni nel file form.html (Fonte: Wikipedia) <?php //Prepara la query in una variabile $query = "SELECT * FROM users WHERE user='".$_POST['user']."' AND pwd='".$_POST['pwd']."'"; //Esegue la query (supponiamo che sia già aperta una connessione valida al database e $db è lo stato) $sql = mysql_query($query,$db); //Conta il numero di righe trovate (se questo numero è maggiore di 0 i dati immessi sono corretti) if(mysql_affected_rows($sql)>0) { //Esegue la convalida dell'autenticazione e permette l'accesso a pagine protette } ?> Fig. 2 - Istruzioni nel file login.php (Fonte: Wikipedia) spondano a quelli nel database degli accessi in SQL. Si noti che in questo file c’è l’istruzione SQL <select> per cercare i dati nel database. L’utente da browser compila nel form i due campi <Username> e <Password> che vengono passati a login.php nelle variabili <$_POST[‘user’]> e <$_POST[‘pwd’]>. L’attacco SQLIA consiste nell’inserire nello script PHP dati arbitrari tramite il form in HTML, nell’ipotesi che lo script non compia i dovuti controlli sui caratteri di <Username> e <Password>, e si possano sfruttare alcuni caratteri speciali negli operatori. In questo esempio, si supponga che l’attaccante conosca l’identificativo di un utente, ma non la relativa password; egli prova allora a inserire il nome utente <pippo>, che effettivamente esiste, e come password <’ OR user=’pippo>. La combinazione dei dati inseriti nel form con lo script in php senza specifici controlli porta a creare un’interrogazione SQL come: <SELECT * FROM users WHERE USER=’pippo’ AND pwd=’’ OR USER=’pippo’>. La disgiunzione inclusiva OR restituisce TRUE se una delle due condizioni è vera. La condizione per l’utente <pippo> è verificata e quindi il login va a buon fine, pur non conoscendo la password. Anche se non si conosce il nome corretto di un utente, l’attaccante può provare a settare con operatori speciali quali: <’ or ‘1’=’1> <’ or ‘1’=’1’ — ‘> <’ or ‘1’=’1’ ({ ‘> <’ or ‘1’=’1’ /* ‘> L’istruzione SQL diviene <SELECT * FROM `users` WHERE `name` = ‘’ OR ‘1’=’1’;> <SELECT * FROM `users` WHERE `name` = ‘’ OR ‘1’=’1’ — ‘;> ed essendo sempre vero che 1=1, l’attaccante effettua l’accesso pur non conoscendo né il nome di un utente né la sua password. L’esempio mostrato è semplice e serve a capire la logica dell’attacco con il presupposto che lo script non abbia alcun controllo sui caratteri di input nel form. Si deve tener conto che i più recenti attacchi combinano un SQLIA con altri tipi di attacco, ad esempio un DoS/DDoS (Denial of Service/Distributed DoS) o un attacco al DNS (Domain Name System). Per portare un serio SQLIA l’attaccante dovrebbe conoscere la logica dell’applicazione web e di come è strutturato il database SQL. Ma con un poco di pazienza e facendo alcune prove, dotati di un solo browser, si possono scoprire molte informazioni. Basta ad esempio inserire nel campo del nome utente della pagina di login di un sito web un carattere apostrofo, <’>, ed a secondo delle risposte che si ottengono si può comprendere se l’applicazione è più o meno attaccabile. La protezione principale è il controllo dei dati in input da parte del programma, tenendo conto di tutte le possibili combinazioni di caratteri speciali e di operatori, e bloccandoli. Per i programmi già in uso è opportuno verificare che questi controlli ci siano, ed in caso contrario modificare opportunamente il programma. Per la verifica di vulnerabilità tipo SQL injection sono disponibili sul mercato dei software di verifica (scanning), sia proprietari che open source. È poi opportuno che i messaggi con i codici di errore non forniscano, seppur involontariamente, informazioni preziose per un attaccante… che ci sta provando. È opportuno configurare il sistema in modo che fornisca messaggi d’errore abbastanza generici e senza informazioni di dettaglio. Inoltre è necessario verificare che i privilegi usati dagli utenti sul database SQL non siano quelli superiori da amministratore; in caso contrario occorre ridurli. Infine, come per tutto il software, è indispensabile aggiornare tempestivamente il database server e gli interpreti degli script, soprattutto per eliminare eventuali vulnerabilità. luglio-agosto 2011 office automation 89