Domanda

.NET, Java e altre API di database di alto livello in vari linguaggi spesso forniscono tecniche note come istruzioni preparate e associazione di parametri anziché inviare comandi di testo semplice al server del database.Quello che vorrei sapere è cosa succede quando esegui un'istruzione come questa:

SqlCommand cmd = new SqlCommand("GetMemberByID");
cmd.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("@ID", memberID);
para.DbType = DbType.Integer;
cmd.Parameters.Add(param);

So che questa è una buona pratica.Gli attacchi SQL injection vengono ridotti al minimo in questo modo.Ma cosa succede esattamente dietro le quinte quando esegui queste affermazioni?Il risultato finale è ancora una stringa sicura SQL?In caso contrario, qual è il risultato finale?E questo è sufficiente per prevenire attacchi SQL injection?

È stato utile?

Soluzione

La pagina del manuale MySQL sulle dichiarazioni preparate fornisce molte informazioni (che dovrebbero applicarsi a qualsiasi altro RDBMS).

Fondamentalmente, la tua istruzione viene analizzata ed elaborata in anticipo e i parametri vengono inviati separatamente invece di essere gestiti insieme al codice SQL.Ciò elimina gli attacchi SQL injection perché l'SQL viene analizzato prima ancora che i parametri vengano impostati.

Altri suggerimenti

in parole povere:se viene inviata un'istruzione preparata, il DB utilizzerà un piano se disponibile, non è necessario ricreare un piano ogni volta che viene inviata questa query ma sono cambiati solo i valori dei parametri.questo è molto simile a come funzionano i procs, l'ulteriore vantaggio di procs è che puoi dare il permesso solo tramite procs e non alle tabelle sottostanti

Se utilizzi MS SQL, carica il profiler e vedrai quali istruzioni SQL vengono generate quando utilizzi query con parametri.Ecco un esempio (sto utilizzando Enterprise Libary 3.1, ma i risultati sono gli stessi utilizzando direttamente SqlParameters) rispetto a SQL Server 2005:

string sql = "SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did";
Database db = DatabaseFactory.CreateDatabase();
using(DbCommand cmd = db.GetSqlStringCommand(sql))
{
  db.AddInParameter(cmd, "DomName", DbType.String, "xxxxx.net");
  db.AddInParameter(cmd, "Did", DbType.Int32, 500204);

  DataSet ds = db.ExecuteDataSet(cmd);
}

Questo genera:

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did',
  N'@DomName nvarchar(9),
  @Did int',
  @DomName=N'xxxxx.net',
  @Did=500204

Puoi anche vedere qui, se i caratteri delle virgolette sono stati passati come parametri, vengono di conseguenza sottoposti a escape:

db.AddInParameter(cmd, "DomName", DbType.String, "'xxxxx.net");

exec sp[underscore]executesql N'SELECT * FROM tblDomains WHERE DomainName = @DomName AND DomainID = @Did',
  N'@DomName nvarchar(10),
  @Did int',
  @DomName=N'''xxxxx.net',
  @Did=500204
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top