Sicurezza: SQL Injection

March 16th, 2007 by MP

Quando si parla di php non si può tralasciare l'argomento sicurezza. Essendo uno dei linguaggi di scripting più utilizzati per costruire siti internet dinamici è allo stesso tempo più preso di mira da hackers (per lo più lamers) che sfruttano le vulnerabilità dei siti internet php per eseguire comandi o e impadronirsi del sistema su cui è hostato il sito.

La cosa che fa tremare di più gli sviluppatori di siti internet in PHP non sono gli attacchi DoS o bruteforce ma lo sfruttamento delle sviste degli stessi programmatori!

E' come se un costruttore di automobili si dimenticasse di fissare i cardini sulla portiera delle auto rendendo cosi inutile la serratura!

Queste sviste purtroppo non sono sempre lampanti sopratutto negli script di svariate migliaia di linee di codice e anche i programmatori senior spesso cadono in questo genere di errori.

Ma se una persona comune pensa che una svista potrebbe permettere di inserire in un campo una data di nascita fasulla (come ad esempio 31/2/1984), per altri programmatori significa ben altro. Ad esempio la possibilità di inserire dei comandi particolari che in determinati casi (molto raramente) possono essere eseguiti creando anche pieno accesso alle directory e ai files del sito.

Stiamo parlando dell'SQL Injection, una tecnica particolare che combina lo sfruttamento di vulnerabilità nei campi di inserimento allo scopo di far eseguire dei comandi SQL.

Per spiegare questo concetto immaginatevi un form, come quello di google. Se google avesse un database e ogni ricerca effettuata da qualsiasi utente venisse salvata nel database allora ci troveremo di fronte ad uno script del genere:

PHP:
<?php

$query = "INSERT INTO queries (query) VALUES ('".$_POST["ricerca"]."')";

mysql_query($query);

?>

Ovviamente questo è uno script da polli, ma molto spesso capita di trovare degli script simili: daltronde chi si aspetta che qualcuno inserisca nel campo della ricerca parametri SQL?

Continuando il discorso ipotizziamo l'inserimento nel form di richiesta una stringa tipo:

SQL:
');INSERT INTO administrators (name,password) VALUES ('mp','mp

In questo caso inseriremmo nel database nella tabella administrators il nostro nome cosicchè da poter accedere ad un ipotetico pannello di controllo di google.

Naturalmente questo è un esempio che è semi fantascienza, ma vi fa capire che basta poco per lasciare aperta una possibilità di inserire all'interno del vostro database informazioni non autorizzate e lasciando cosi spazio a qualche bontempone che vi vuole fare una sorpresa.

Un altro esempio di sql injection è l'esempio classico dal form di login: immaginiamo un form di login di questo tipo:

HTML:
<form action='login.php' method='post'>
   Utente <input type='text' name='user' />
   Password <input type='password' name='pass' />
   <input type='submit'/>
</form>

Ne avete visti/fatti a centinaia, che succede però nella parte del server, cioè come gestiamo le informazioni mandate nel form? Beh se siamo un po' spavaldi e non ci curiamo della sicurezza...così

PHP:
<?php

$query = "SELECT * FROM users WHERE user='".$_POST["user"]."' AND pwd='".$_POST["pass"]."'";
$result= mysql_query($query);

?>

Naturalmente è uno script valido e funzionante, quindi che succederebbe se noi volessimo utilizzare una stringa SQL come nome utente "administrator" e password "boh' OR '1'='1"? La query che ne risulterà sarà:

SQL:
SELECT * FROM users WHERE user='administrator' AND pass='boh' OR '1'='1'

Siccome nella query è presente OR 1=1 allora la query darà il primo risultato cioè quello sperato da chi si collega con i dati corretti perchè anche se la password è sbagliata, 1=1 è vera perciò si verrà autenticati da amministratori.

Spero che questo post vi serva per creare codice più robusto ed evitare che un piccolo errore di valutazione possa causare danni grossisimi.

MP

Posted in PHP Security |

2 Responses

  1. Myky Says:

    Cavolo è bastardissima come cosa! E tra l’altro semplicissima!!! Ma ki ci va a pensare?

    Cmq se si salvano le password in md5 ( md5( $password ) ) si dovrebbe togliere il problema quanto meno nel form del login…. E per il resto usando la sostituzione dei caratteri ( htmlchars() ) o addslashes() per aggiungere i caratteri di escape ad ogni stringa ke va aggiunta direttamente…

    Tnx ;)

  2. MP Says:

    Beh si pensa che non si utilizzi il $_POST[] all’interno delle query ma sia prima controllato da espressioni regolari o semplicemente parsato come hai detto tu evitando cosi che nelle var siano presenti delle query maligne

    cmq benvenuto miky!

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.