Je suis très novice dans le domaine des bases de données. Maintenant , je peux écrire SELECT
, UPDATE
, DELETE
et les INSERT
commandes. Mais j'ai vu de nombreux forums où nous préférons écrire:
SELECT empSalary from employee where salary = @salary
...au lieu de:
SELECT empSalary from employee where salary = txtSalary.Text
Pourquoi préférons-nous toujours utiliser des paramètres et comment les utiliserais-je?
Je voulais connaître l'utilisation et les avantages de la première méthode. J'ai même entendu parler de l'injection SQL mais je ne la comprends pas entièrement. Je ne sais même pas si l'injection SQL est liée à ma question.
sql
sql-server
sql-injection
Sablonneux
la source
la source
Réponses:
L'utilisation de paramètres permet d'éviter les attaques par injection SQL lorsque la base de données est utilisée conjointement avec une interface de programme telle qu'un programme de bureau ou un site Web.
Dans votre exemple, un utilisateur peut exécuter directement du code SQL sur votre base de données en créant des instructions dans
txtSalary
.Par exemple, s'ils devaient écrire
0 OR 1=1
, le SQL exécuté seraitpar lequel tous les salaires seraient retournés.
De plus, un utilisateur pourrait exécuter des commandes bien pires contre votre base de données, y compris la supprimer s'il écrivait
0; Drop Table employee
:Le tableau
employee
serait alors supprimé.Dans votre cas, il semble que vous utilisez .NET. L'utilisation des paramètres est aussi simple que:
C #
VB.NET
Modifier le 25/04/2016:
Selon le commentaire de George Stocker, j'ai changé l'exemple de code pour ne pas l'utiliser
AddWithValue
. En outre, il est généralement recommandé d'encapsuler lesIDisposable
s dans desusing
instructions.la source
Insert Into table (Col1, Col2) Values (@Col1, @Col2)
. Dans votre code, vous ajouteriez plusieursAddWithValue
s.parameter.Value = someValue
.Vous avez raison, cela est lié à l' injection SQL , qui est une vulnérabilité qui permet à un utilisateur malveillant d'exécuter des déclarations arbitraires sur votre base de données. Cette bande dessinée XKCD préférée de l'ancien temps illustre le concept:
Dans votre exemple, si vous utilisez simplement:
Vous êtes ouvert à l'injection SQL. Par exemple, disons que quelqu'un entre txtSalary:
Lorsque vous exécutez cette requête, il effectuera un
SELECT
et unUPDATE
ouDROP
, ou ce qu'ils voulaient. Le--
à la fin commente simplement le reste de votre requête, ce qui serait utile dans l'attaque si vous concaténiez quoi que ce soit aprèstxtSalary.Text
.La bonne façon est d'utiliser des requêtes paramétrées, par exemple (C #):
Avec cela, vous pouvez exécuter la requête en toute sécurité.
Pour savoir comment éviter l'injection SQL dans plusieurs autres langues, consultez bobby-tables.com , un site Web géré par un utilisateur SO .
la source
En plus d'autres réponses, il faut ajouter que les paramètres aident non seulement à empêcher l'injection SQL, mais peuvent également améliorer les performances des requêtes . Le serveur SQL met en cache les plans de requêtes paramétrés et les réutilise lors de l'exécution répétée de requêtes. Si vous n'avez pas paramétré votre requête, le serveur sql compilerait un nouveau plan à chaque exécution de requête (avec une certaine exclusion) si le texte de la requête était différent.
Plus d'informations sur la mise en cache du plan de requête
la source
Deux ans après ma première tentative , je récidive ...
Pourquoi préférons-nous les paramètres? L'injection SQL est évidemment une grande raison, mais se pourrait-il que nous aspirions secrètement à revenir à SQL en tant que langage . SQL dans les chaînes littérales est déjà une pratique culturelle étrange, mais au moins vous pouvez copier et coller votre requête dans le studio de gestion. SQL construit dynamiquement avec des conditions et des structures de contrôle du langage hôte, lorsque SQL a des conditions et des structures de contrôle, est juste une barbarie de niveau 0. Vous devez exécuter votre application en mode débogage, ou avec une trace, pour voir quel SQL elle génère.
Ne vous arrêtez pas uniquement avec des paramètres. Allez jusqu'au bout et utilisez QueryFirst (avertissement: que j'ai écrit). Votre SQL vit dans un fichier .sql. Vous le modifiez dans la fabuleuse fenêtre de l'éditeur TSQL, avec la validation de la syntaxe et Intellisense pour vos tables et colonnes. Vous pouvez attribuer des données de test dans la section des commentaires spéciaux et cliquer sur «jouer» pour exécuter votre requête directement dans la fenêtre. Créer un paramètre est aussi simple que de mettre "@myParam" dans votre SQL. Ensuite, chaque fois que vous enregistrez, QueryFirst génère le wrapper C # pour votre requête. Vos paramètres apparaissent, fortement typés, comme arguments des méthodes Execute (). Vos résultats sont renvoyés dans un IEnumerable ou une liste de POCO fortement typés, les types générés à partir du schéma réel renvoyé par votre requête. Si votre requête ne s'exécute pas, votre application ne sera pas compilée. Si votre schéma de base de données change et que votre requête s'exécute mais que certaines colonnes disparaissent, l'erreur de compilation pointe vers la ligne de votre codequi tente d'accéder aux données manquantes. Et il existe de nombreux autres avantages. Pourquoi voudriez-vous accéder aux données d'une autre manière?
la source
En SQL, lorsqu'un mot contient le signe @, cela signifie qu'il est variable et nous utilisons cette variable pour définir une valeur et l'utiliser sur la zone numérique du même script sql car il n'est limité que sur le script unique alors que vous pouvez déclarer beaucoup de variables de même type et nom sur de nombreux scripts. Nous utilisons cette variable dans un lot de procédures stockées car les procédures stockées sont des requêtes pré-compilées et nous pouvons transmettre des valeurs dans ces variables à partir du script, du bureau et des sites Web pour plus d'informations, lisez Declare Local Variable , Sql Stored Procedure et SQL injections .
Lisez également Protéger de l'injection SQL, il vous expliquera comment protéger votre base de données.
J'espère que cela vous aidera à comprendre également toute question commentez-moi.
la source
D'autres réponses expliquent pourquoi les paramètres sont importants, mais il y a un inconvénient! Dans .net, il existe plusieurs méthodes pour créer des paramètres (Add, AddWithValue), mais elles nécessitent toutes que vous vous inquiétiez, inutilement, du nom du paramètre, et elles réduisent toutes la lisibilité du SQL dans le code. Lorsque vous essayez de méditer sur le SQL, vous devez chercher au-dessus ou en dessous pour voir quelle valeur a été utilisée dans le paramètre.
Je prétends humblement que ma petite classe SqlBuilder est le moyen le plus élégant d'écrire des requêtes paramétrées . Votre code ressemblera à ceci ...
C #
Votre code sera plus court et beaucoup plus lisible. Vous n'avez même pas besoin de lignes supplémentaires et, lorsque vous relisez, vous n'avez pas besoin de chercher la valeur des paramètres. La classe dont vous avez besoin est ici ...
la source
AddWithValue
peut provoquer des problèmes de conversion implicites.Ancien poste, mais voulait s'assurer que les nouveaux arrivants connaissent les procédures stockées .
Ma valeur de 10 ¢ ici est que si vous êtes capable d'écrire votre instruction SQL en tant que procédure stockée , c'est à mon avis l'approche optimale. J'utilise TOUJOURS des procs stockés et je ne boucle jamais les enregistrements de mon code principal. Par exemple:
SQL Table > SQL Stored Procedures > IIS/Dot.NET > Class
.Lorsque vous utilisez des procédures stockées, vous pouvez restreindre l'utilisateur à l' autorisation EXECUTE uniquement, réduisant ainsi les risques de sécurité .
Votre procédure stockée est intrinsèquement paramétrée et vous pouvez spécifier des paramètres d'entrée et de sortie.
La procédure stockée (si elle renvoie des données via une
SELECT
instruction) est accessible et lue exactement de la même manière que vous le feriez pour uneSELECT
instruction régulière dans votre code.Il s'exécute également plus rapidement car il est compilé sur le serveur SQL.
Ai-je également mentionné que vous pouvez faire plusieurs étapes, par exemple
update
une table, vérifier les valeurs sur un autre serveur de base de données, puis une fois finalement terminé, retourner les données au client, le tout sur le même serveur, et aucune interaction avec le client. C'est donc BEAUCOUP plus rapide que de coder cette logique dans votre code.la source