w3ctrlhacking-sql-injection-1024x439[1]

Per la gestione dei problemi legati ad attacchi di Sql Injection uno dei metodi possibili è usare delle query parametriche nel nostro codice. Fondamentalmente si costruisce la nostra query sfruttando dei Placeholder del tipo "@NomeParametro" e si ultilizza la collection parameters della classe SqlCommand.

Per query del tipo "where = [condition] " il meccanismo è di facile utilizzo:

var myCmd = new SqlCommand("SELECT * FROM dbo.Users WHERE UserName = @UserName");


Ma in caso di un filtro del tipo "IN (list of [condition])" ? come possiamo evitare di creare la nostra query concatenando le condizioni di IN ma utilizzando sempre i Parameters?

Esempio :Abbiamo la nostra funzione per la cancellazione massiva di utenti che prende in input la lista di utenti da cancellare.

Dalla nostra lista utenti otteniamo la nostra clausala di where e concatendo le due stringhe otteniamo il comando sql da eseguire.

        public bool DeleteUsers(IList<string> users)
{
const string querySql = "DELETE FROM Users WHERE UserName IN ({0})";
try
{
users = users.Select(i => string.Format("'{0}'", i)).ToString();
var inClause = string.Join(",", users);
querySql = string.format(querySql,inClause);

.......
}
catch (Exception ex)
{
throw;
}
}

Come possiamo eseguire la stessa operazione usando invece dei SqlParameters?

        public bool DeleteUsers(IList<string> users)
{
const string querySql = "DELETE FROM Users WHERE UserName IN ({0})";
try
{
var parms = users.Select((s, i) => "@p" + i.ToString(CultureInfo.InvariantCulture)).ToArray();
var inClause = string.Join(",", users);
using (var conn = GetConnection())
{
using (var dbCommand = new SqlCommand(string.Format(querySql, inClause), conn))
{
dbCommand.CommandType = CommandType.Text;
for (var i = 0; i < users.Count; i++)
{
dbCommand.Parameters.Add(parms[i], lottis[i]);
}
.....
.....
}
}
}
catch (Exception ex)
{
throw;
}
}

Andiamo a crearci una query non più di questo tipo :

DELETE FROM Users WHERE UserName IN ('user1','user2','user2'....);
ma fatta così:
DELETE FROM Users WHERE UserName IN (@p1,@p2,@p3....);
Sostituendo a ogni username un placeholder e poi creando tanti SqlParameter quanti placeholder abbiamo creato.
Abbiamo sempre costruito la nostra query usando una concatenazione di stringhe ma sfruttando i placeholder e sostituendoli con i rispettivi parametri ci siamo messi al sicuro da possibili attacchi di SqlInjection.

p.s. Per chi non ha familiarità con linq :
var parms = users.Select((s, i) => "@p" + i.ToString(CultureInfo.InvariantCulture)).ToArray();

Equivale a 

                var list = new List<string>();
                for (var i = 0; i < lottis.Count; i++)
                {
                    list.Add("@p" + i.ToString(CultureInfo.InvariantCulture));
                }
                var parms = list.ToArray();

Autore:


blog comments powered by Disqus

 

Calendar

<<  dicembre 2017  >>
lunmarmergiovensabdom
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Vedi i post nel calendario più grande

Category list