Comment les requêtes paramétrées aident-elles contre L'injection SQL?

Dans les requêtes 1 et 2, le texte de la zone de texte est inséré dans la base de données. Quelle est la signification de la requête paramétrée ici?

1.>-------------

SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(@TagNbr);" , conn);

cmd.Parameters.Add("@TagNbr", SqlDbType.Int);

cmd.Parameters["@TagNbr"].Value = txtTagNumber.Text;

2.>--------------

int tagnumber = txtTagNumber.Text.ToInt16(); /* EDITED */

INSERT into Cars values(tagnumber.Text); /* then is it the same? */

Aussi, ici j'utiliserais la validation D'Expression régulière pour arrêter l'insertion de caractères illégaux.

41
demandé sur Nondeterministic narwhal 2011-03-29 09:50:33

6 réponses

Les requêtes paramétrées effectuent une substitution correcte des arguments avant d'exécuter la requête SQL. Il supprime complètement la possibilité d'une entrée "sale" modifiant la signification de votre requête. Autrement dit, si L'entrée contient SQL, elle ne peut pas faire partie de ce qui est exécuté car le SQL n'est jamais injecté dans l'instruction résultante.

41
répondu OJ. 2011-03-29 05:54:26

L'injection Sql se produit lorsqu'un paramètre possible contient sql et que les chaînes ne sont pas gérées comme il se doit

Par exemple:

var sqlquerywithoutcommand = "select * from mytable where rowname =  '" + condition+''";

Et la condition est une chaîne provenant de l'utilisateur dans la requête. Si la condition est malveillante dites par exemple:

var sqlquerywithoutcommand = "select * from mytable where rowname =  '" + "a' ;drop table  mytable where '1=1"+"'";

Vous pourriez finir par exécuter des scripts malveillants.

Mais en utilisant des paramètres, l'entrée sera nettoyée de tous les caractères qui pourraient échapper aux caractères de chaîne...

, Vous pouvez être assuré, peu importe ce qui vient en elle ne pas être en mesure d'exécuter injecter des scripts.

En utilisant l'objet command avec des paramètres, le sql réellement exécuté ressemblerait à ceci

select * from mytable where rowname = 'a'';drop table mytable where 1=1'''

Dans essense, il recherchera une ligne avec rowname = a'; drop table mytable where 1=1' et ne pas exécuter le script restant

15
répondu Mulki 2011-03-29 06:19:02

Imaginez une requête SQL dynamique

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND
Pass=' + password

Donc, une simple injection sql serait juste pour mettre le nom D'utilisateur comme ' OR 1=1-- cela ferait effectivement la requête sql:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS='
+ password

Cela dit, sélectionnez tous les clients dont le nom d'utilisateur est vide ( " ) ou 1 = 1, qui est un booléen, assimilant à vrai. Ensuite, il utilise -- de commentaire le reste de la requête. Donc, cela va juste imprimer tous les table client, ou faire ce que vous voulez avec elle, si la connexion, il va ouvrir une session avec les privilèges du premier utilisateur, qui peuvent souvent être administrateur.

Maintenant, les requêtes paramétrées le font différemment, avec du code comme:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

Paramètres.ajouter ("utilisateur", nom d'utilisateur) paramètres.ajouter ("passer", mot de passe)

Où le nom d'utilisateur et le mot de passe sont des variables pointant vers nom d'utilisateur et mot de passe entrés

Maintenant, à ce stade, vous pensez peut-être, cela ne changera rien à tous. Sûrement vous pouvez toujours simplement mettre dans le nom d'utilisateur champ quelque chose comme Nobody ou 1 = 1'--, faisant effectivement la requête:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND
Pass=?'

Et cela semblerait être un argument valide. Mais, vous avez tort.

La façon dont les requêtes paramétrées fonctionnent, est que sqlQuery est envoyé en tant que requête, et la base de données sait exactement ce que cette requête fera, et ce n'est qu'alors qu'il insérera le nom d'utilisateur et les mots de passe simplement en tant que valeurs. Cela signifie qu'ils ne peuvent pas affecter la requête, car la base de données sait ce que la requête va faire. Donc, en ce cas, il aurait l'air d'un nom d'utilisateur de "Nobody OR 1=1'--" et un mot de passe vide, qui devrait venir faux.

Prises à partir de

3
répondu Ruben Steins 2016-12-21 21:29:38

Requêtes paramétrées gère tout-Pourquoi aller à la peine?

Avec les requêtes paramétrées, en plus de l'injection générale, vous obtenez tous les types de données gérés, les nombres (int et float), les chaînes (avec des guillemets intégrés), les dates et les heures (Pas de problèmes de formatage ou de localisation .ToString () n'est pas appelé avec la culture invariante et votre client se déplace vers une machine avec un format de date inattendu).

1
répondu Cade Roux 2011-03-29 06:01:25

Les requêtes paramétrées permettent au client de transmettre les données séparément dans le texte de la requête. Où sur la plupart des textes libres vous feriez validation + escaping. Bien sûr, le paramétrage n'aide pas contre d'autres types d'injection, mais comme les paramètres sont passés séparément, ils ne sont pas utilisés comme requête de texte d'exécution.

Une bonne analogie serait le bit d'exécution "récent" utilisé avec la plupart du processeur et du système d'exploitation modernes pour protéger du débordement de tampon. Il permet toujours le débordement de tampon mais empêche l'exécution des données injectées.

1
répondu dvhh 2011-03-29 06:11:02

Il est tout à fait compréhensible que l'on se sente ainsi.

sqlQuery = "select * from users where username='+username+';"

Vs

sqlQuery = "select * from users where username=@username;"

Les deux requêtes ci-dessus semblent faire la même chose.Mais ils ne le font pas.

Le premier utilise input to pour une requête, le second décide de la requête mais ne substitue que les entrées telles qu'elles sont lors de l'exécution de la requête.

Pour être plus clair, les valeurs des paramètres sont situées quelque part sur la pile où la mémoire des variables est stockée et est utilisée pour la recherche lorsque nécessaire.

Donc, si nous devions donner ' OR '1'='1 comme entrée dans username, le premierconstruirait dynamiquement de nouvelles requêtes ou requêtes dans le cadre de la chaîne de requête sql sqlQuery qui est ensuite exécutée.

Sur la même entrée, ce dernier recherchera ' OR '1'=' dans le champ username de la table users avec la requêtestatiquement spécifiée dans la chaîne de requête sqlQuery

Juste pour le consolider, voici comment vous utilisez les paramètres pour faire une requête:

SqlCommand command = new SqlCommand(sqlQuery,yourSqlConnection);

SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@username";
parameter.Value = "xyz";

command.Parameters.Add(parameter);
1
répondu ant_1618 2016-04-11 12:45:47