Question

.NET, Java et d'autres API de base de données de haut niveau dans divers langages fournissent souvent des techniques connues sous le nom d'instructions préparées et de liaison de paramètres, par opposition à l'envoi de commandes en texte brut au serveur de base de données.Ce que j'aimerais savoir, c'est ce qui se passe lorsque vous exécutez une instruction comme celle-ci :

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

Je sais que c'est une bonne pratique.Les attaques par injection SQL sont ainsi minimisées.Mais que se passe-t-il exactement sous le capot lorsque vous exécutez ces déclarations ?Le résultat final est-il toujours une chaîne SQL sécurisée ?Si non, quel est le résultat final ?Et est-ce suffisant pour empêcher les attaques par injection SQL ?

Était-ce utile?

La solution

La page de manuel MySQL sur les instructions préparées fournit de nombreuses informations (qui devraient s'appliquer à tout autre SGBDR).

Fondamentalement, votre instruction est analysée et traitée à l'avance, et les paramètres sont envoyés séparément au lieu d'être traités avec le code SQL.Cela élimine les attaques par injection SQL car le SQL est analysé avant même que les paramètres ne soient définis.

Autres conseils

en termes simples :si une instruction préparée est envoyée, la base de données utilisera un plan s'il est disponible, elle n'a pas besoin de recréer un plan à chaque fois que cette requête est envoyée mais seules les valeurs des paramètres ont changé.ceci est très similaire au fonctionnement des procs, l'avantage supplémentaire des procs est que vous pouvez accorder l'autorisation via les procs uniquement et pas du tout aux tables sous-jacentes.

Si vous utilisez MS SQL, chargez le profileur et vous verrez quelles instructions SQL sont générées lorsque vous utilisez des requêtes paramétrées.Voici un exemple (j'utilise Enterprise Libary 3.1, mais les résultats sont les mêmes en utilisant directement SqlParameters) avec 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);
}

Cela génère :

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

Vous pouvez également voir ici que si des guillemets ont été passés en paramètres, ils sont échappés en conséquence :

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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top