Progettazione… Programmazione… Soluzione…
Hacking: SQL Injection
Tutti coloro che hanno lavorato almeno una volta con un database, soprattutto per quanto riguarda la gestione di utenti e relative password, sapranno che la tecnica più diffusa per appropriarsi di dati sensibili, è la tecnica chiamata Sql Injection.
La SQL injection è una tecnica dell’hacking mirata a colpire le applicazioni web che si appoggiano su un database di tipo SQL. Questo exploit sfrutta l’inefficienza dei controlli sui dati ricevuti in input ed inserisce codice maligno all’interno di una query SQL. Le conseguenze prodotte sono imprevedibili per il programmatore: l’Sql Injection permette al malintenzionato di autenticarsi con ampi privilegi in aree protette del sito (ovviamente, anche senza essere in possesso delle credenziali d’accesso) e di visualizzare e/o alterare dati sensibili.
Di seguito un esempio concreto per valutare le caratteristiche e la pericolosità di questa tecnica, con i seguenti componenti:
- db_name – Questo è il database al quale faremo riferimento;
- users – Questa è la tabella all’interno del DB che conterrà i dati degli utenti, in particolare username e password;
- login.php – Pagina php contenente un semplice script per verificare se l’username e password forniti sono corretti (quindi sono all’interno del DB);
- form.html – Pagina html che chiede i dati (username e password) tramite browser e richiama lo script php.
Vediamo dapprima il codice della pagina form.html che contiene un semplice form per la richiesta di username e password:
1 2 3 4 5 | <form action='login.php' method='post'> Username: <input type='text' name='username' /> Password: <input type='password' name='password' /> <input type='submit' value='Login' /> </form> |
Di sopra ho trascritto solo la parte della pagina html contenente il form, che ha solo due campi, uno per l’username e uno per la password. L’azione del form, è impostata per richiamare la pagina login.php che recupererà i dati immessi tramite $_POST['user'] e $_POST['pwd']. Dopo aver ricevuto questi dati, lo script PHP interagisce con il database per verificarne la validità. Ecco quindi il codice della pagina login.php:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?php // CONNESSIONE AL DATABASE $connessione = mysql_connect("db_address","db_username","db_password") or die("Errore!!"); // SELEZIONE DEL DATABASE mysql_select_db("db_name", $connessione) or die("Errore!!"); // PREPARO LA QUERY $query = "SELECT * FROM users WHERE username='".$_POST['username']."' AND password='".$_POST['password']."'"; // ESEGUO LA QUERY $sql = mysql_query($query, $connessione); // CONTO IL NUMERO DI RISULTATI TROVATI // 1. I DATI SONO VALIDI // 0. DATI NON VALIDI if( mysql_affected_rows($sql) > 0 ) { echo "LOGIN ESEGUITO CON SUCCESSO"; } else { echo "DATI NON CORRETTI"; } ?> |
La tecnica di hackin Sql Injection consiste proprio nell’inviare allo script PHP dati maligni tramite il form in HTML. In questo caso, basta immettere per esempio come username nerthase e come password ‘OR ’1′=’1 per accedere con le credenziali dell’utente nerthase (ammesso che esso esista). La query per il database diventa quindi:
La clausola WHERE è sempre soddisfatta, in quanto la seconda parte di essa, che è in OR, è sempre verificata. L’attaccante quindi, è riuscito ad effettuare l’accesso con l’account nerthase anche senza conoscere la relativa password. Questa tecnica è molto diffusa tra la comunità Hacker, e soprattutto tra i dilettanti che si avvicinano per la prima volta a questo mondo. L’unica possibilità per evitare questo tipo di attacco, è un controllo sui dati ricevuti nello script PHP. Questo può essere fatto in diversi modi, a seconda delle necessità dell’applicazione:
- forzare il tipo dei dati ricevuti (se ci si aspetta un valore numerico, considerare validi solo input numerici;
- effettuare l’escape dei dati ricevuti (ogni linguaggio, solitamente, mette a disposizione particolari strumenti per questo scopo);
- criptare le credenziali di accesso prima di inserirle nella query SQL (evitare che le informazioni sensibili siano memorizzate nel DB in chiaro).
Questi metodi possono essere anche combinati al fine di rafforzare la sicurezza dell’applicazione. Occorre, quindi, prestare particolare attenzione a tutte le varianti di un input, tenendo conto di ogni possibile (oppure improbabile) ipotesi. Potete approfondire questo argomento, per quanto riguarda la protezione contro l’SQL Injection nel relativo articolo.
| Stampa l'articolo | Questo articolo è stato pubblicato da nerthase il 21 marzo 2010 alle 22:36, ed è archiviato come Guide, Informatica & co, PHP & MySql. Puoi seguire i commenti a questo post attraverso RSS 2.0. Puoi pubblicare un commento o segnalare un trackback dal tuo sito. |




