Recentemente mi sono trovato a dover metter mano su portali che frequentemente mostravano dei contenuti indesiderati.
Ma qual'era la causa? La risposta è molto semplice: SQL Injection.
SQL Injection consiste in un attacco informatico che sfrutta la cattiva pratica di molti sviluppatori di concatenare le stringhe destinate ad un database server.
Prendiamo ad esempio la seguente query: "select * from utenti where nome like ' " + TextBox1.Text + "%' ".
Un utente del web che dovesse cercare "Alessio" causerebbe l'esecuzione della query: "select * from utenti where nome like 'Alessio%' ".
Non essendoci alcuna validazione del contenuto della TextBox, un hacker potrebbe sfruttare questa vulnerabilità inserendo nella casella di testo la stringa: " '' or 'a' like 'a ".
L'istruzione SQL risultante sarebbe la seguente: "select * from utenti where nome like '' or 'a' like 'a%'", causando quindi la restituzione del contenuto completo della tabella utenti.
Questo esempio non è che la punta dell'iceberg. Il peggio ha ancora da venire ma questo deve cominciare a far riflettere gli sviluppatori poco accorti in quanto essere vulnerabili a questo tipo di attacco è contrario alla normativa vigente in materia di privacy (http://www.garanteprivacy.it).
Fino ad ora non abbiamo neppure citato il linguaggio di sviluppo o la tecnologia che il web server usa per eseguire le query sul database. Questo perché sono ininfluenti. Sia questo un sito asp classico, php, jsp, asp.net o cgi, il problema è solo causato dallo sviluppatore che non valida l'input dell'utente e non dalla tecnologia usata.
Validare bene l'input utente non è una cosa da inventare. La soluzione sta nella collection dei parametri del command.
Sia che parliamo di ado classico che di ado.net, entrambi prevedono l'uso dei command e di una collection di parametri.
public function LeggiUtenti(StartDate As DateTime ) As DataTable
Dim Cnn As new SqlConnection("Server=localhosto;Database=pubs;Trusted_Connection=True;")
Dim Cmd As new SqlCommand("Select * from utenti where data > @Data",Cnn)
Cmd.Parameters.Add("@Data", SqlDbType.DateTime).Value = StartDate
Dim Da As new SqlDataAdapter(Cmd)
Dim Dt As new DataTable()
Try
Da.Fill(Dt)
Catch(Exception)
return null
End Try
return Dt
End Function
Avendo utilizzato il parametro (@Data nell'esempio) e l'aggiunta del parametro nella collection dei parameters, abbiamo eliminato i rischi da injection.
Questa costituisce la migliore soluzione per fronteggiare la SQL Injection ma la sicurezza non si costruisce mai su un solo fronte. Oltre a scrivere codice sicuro è fondamentale aggiungere le altre contromisure sulla configurazione del database server.