Uncategorized

Query, Parametri e SQL Injection

Credo che ogni programmatore nella sua carriera si sia trovato a dover affrontare il problema di come interrogare un database dal proprio programma.
Negli anni, gli strumenti di sviluppo di Microsoft hanno sempre implementato una qualche meccanismo per l’accesso ai dati, il futuro in questo campo sarà probabilmente il LINQ, ma per il momento lo strumento principale per il framework è ADO.net.
In questa entry affronteremo un argomento poco conosciuto ma molto importante per quanto riguarda l’esecuzione delle query

Come tutti ben sapete, per eseguire una query a un database, dopo averne effettuato il collegamento e dopo aver creato un Command semplicemente si associa uno statement SQL e si esegue il comando.
Il metodo è piuttosto semplice, ha il grosso problema della mancanza di digitazione assistita, ma questo inconveniente verrà superato dal già citato LINQ e sarà argomento di molti discorsi futuri.


Al momento, il problema più importante è quello delle istruzioni parametriche; considerate il frammento di codice seguente:
 Cmd = dbConn.CreateCommand
 Cmd.CommandText = "SELECT * FROM articles WHERE ID=" & artID
 Reader = Cmd.ExecuteReader

In una ipotetica tabella contenente una serie di articoli, questo comando recupera il record corrispondente all’articolo con l’identificativo contenuto nella variabile artID, questa variabile potrebbe essere un campo utente.
Questo codice sembra assolutamente innocuo, e probabilmente molti di noi lo hanno usato spesso, ma nasconde una insidia.

Siamo sicuri che artID contenga proprio un numero di ID?
Se questa variabile proviene da un campo utente, cosa succede su viene inserito qualcosa del tipo ;DROP TABLE articles?

Questa tecnica si chiama SQL Injection ed è spesso usata per una operazione di cracking: il primo punto e virgola chiude la query legittima, dopodichè la seconda parte dello statement forza il DB a cancellare tutta la tabella articles!

Ovviamente questo è il caso peggiore, in quanto presuppone nessun controllo sull’input e una gestione allegra delle autorizzazioni, in quanto la connessione del DB avrebbe dovuto essere aperta da un profilo utente con pochi permessi.

A parte queste avvertenza, c’e’ un’altra precauzione che si può prendere: utilizzare i parametri all’interno della query, in modo che un input malformato possa influire solo in una parte limitata della query.
Riscriviamo il codice di prima:

<p class="inlinecode">Dim parm As OleDb.OleDbParameter</p>
dbConn.Open()
 parm = New OleDb.OleDbParameter("@artID", artID)

Cmd = dbConn.CreateCommand
 Cmd.Parameters.Add(parm)
 Cmd.CommandText = "SELECT * FROM articles WHERE ID=@artID"
 Reader = Cmd.ExecuteReader

Il codice è molto semplice: dopo aver dichiarato la variabile parametro, la inizializziamo e la identifichiamo da un nome che inizia con @, nella stessa dichiarazione le associamo anche un valore.
Aggiungiamo, poi, la variabile parametro al comando e nello statement SQL inseriamo il nome del parametro invece di concatenare il nome della variabile.
In questo modo, il testo preso dalla variabile artID non può fare altro che influenzare il valore del campo ID nella query.

Questo è il modo più diretto per creare e usare un oggetto Parameter, ma vi invito a leggere tutta la documentazione sul MSDN per conoscere tutte le caratteristiche di questa classe.
Ricordo infine che l’oggetto parameter non esiste solo per OleDb, ma anche per tutti gli altri provider. Il funzionameto è in pratica identico per tutti, ma leggete sempre l’apposita documentazione per verificare eventuali differenze tra un provider e l’altro.

Annunci
Standard

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...