Il y a en fait deux questions en une. Et la question du titre a très peu à voir avec les préoccupations exprimées par le PO dans les commentaires qui suivent.
Bien que je réalise que pour le PO, c'est son cas particulier qui compte, pour les lecteurs venant de Google, il est important de répondre à une question plus générale, qui peut être formulée comme suit : "la concaténation est-elle aussi sûre que les instructions préparées si je m'assure que chaque littéral que je concatène est sûr ? Je voudrais donc me concentrer sur cette dernière question. Et la réponse est
Définitivement NON.
L'explication n'est pas aussi directe que la plupart des lecteurs le souhaiteraient, mais je vais faire de mon mieux.
J'ai réfléchi à la question pendant un certain temps, ce qui a donné lieu à la article (bien que basé sur l'environnement PHP) où j'ai essayé de tout résumer. Il m'est apparu que la question de la protection contre l'injection SQL est souvent éludée vers des sujets connexes mais plus étroits, comme l'échappement des chaînes de caractères, la classification des types et autres. Bien que certaines de ces mesures puissent être considérées comme sûres lorsqu'elles sont prises isolément, il n'y a pas de système, ni de règle simple à suivre. Il s'agit donc d'un terrain très glissant, qui demande trop d'attention et d'expérience de la part du développeur.
La question de l'injection SQL ne peut être simplifiée à une question de syntaxe particulière. Elle est plus vaste que ce que le développeur moyen avait l'habitude de penser. C'est un méthodologie La question se pose également. Il ne s'agit pas seulement de savoir "quel formatage particulier nous devons appliquer", mais aussi " Comment il faut le faire" également.
(De ce point de vue, l'article de Jon Skeet cité dans l'autre réponse fait plutôt du mal que du bien, car il s'agit à nouveau de pinailler sur un cas limite, en se concentrant sur une question de syntaxe particulière et en omettant d'aborder le problème dans son ensemble).
Lorsque vous essayez d'aborder la question de la protection non pas comme un tout, mais comme un ensemble de questions syntaxiques différentes, vous êtes confronté à une multitude de problèmes.
- la liste des choix de formatage possibles est vraiment énorme. Cela signifie que l'on peut facilement en négliger certains. Ou les confondre (en utilisant chaîne de caractères qui s'échappent pour identifiant par exemple).
- La concaténation signifie que toutes les mesures de protection doivent être prises par le programmeur, et non par le programme. Ce seul problème entraîne plusieurs conséquences :
- une telle mise en forme est manuelle. Manuel signifie extrêmement sujettes à erreur. On peut tout simplement oublier de faire une demande.
- De plus, la tentation est grande de transférer les procédures de formatage dans une fonction centralisée, ce qui perturbe encore plus les choses et gâche des données qui ne seront pas versées dans la base de données.
- lorsque plus d'un développeur est impliqué, les problèmes sont multipliés par un facteur de dix.
- lorsque la concaténation est utilisée, on ne peut pas reconnaître une requête potentiellement dangereuse au premier coup d'œil : elles tous potentiellement dangereux !
Contrairement à cette pagaille, les déclarations préparées sont en effet le Saint Graal :
- elle peut être exprimée sous la forme d'une règle simple et facile à suivre.
- il s'agit d'une mesure essentiellement indétachable, ce qui signifie que le développeur ne peut pas intervenir et, volontairement ou non, gâcher le processus.
- la protection contre l'injection n'est vraiment qu'une effet secondaire des déclarations préparées, dont le but réel est de produire une déclaration syntaxiquement correcte. Et un énoncé syntaxiquement correct est 100% résistant à l'injection. Pourtant, nous avons besoin que notre syntaxe soit correcte malgré toute possibilité d'injection.
- s'il est utilisé dans son intégralité, il protège l'application quelle que soit l'expérience du développeur. Disons qu'il existe une chose appelée injection de second ordre . Et un délire très fort qui dit "afin de protéger", Échapper à toutes les entrées fournies par l'utilisateur ". Combinés ensemble, ils mènent à l'injection, si un développeur prend la liberté de décider, ce qui doit être protégé et ce qui ne doit pas l'être.
(En réfléchissant plus avant, j'ai découvert que l'ensemble actuel de placeholders n'est pas suffisant pour les besoins de la vie réelle et doit être étendu, à la fois pour les structures de données complexes, comme les tableaux, et même les mots-clés ou identifiants SQL, qui doivent parfois être ajoutés à la requête de manière dynamique aussi, mais un développeur est laissé sans armes pour un tel cas, et obligé de se rabattre sur la concaténation de chaînes de caractères, mais c'est une autre question).
Il est intéressant de noter que la controverse de cette question est provoquée par la nature très controversée de Stack Overflow. L'idée du site est de faire usage de les questions particulières des utilisateurs qui les posent directement pour atteindre l'objectif de disposer d'une base de données de des réponses d'ordre général adaptées aux utilisateurs qui viennent de la recherche . L'idée n'est pas mauvaise en soi mais elle échoue dans une situation comme celle-ci : lorsqu'un utilisateur demande à un agent de l'État de lui fournir des informations sur l'état d'avancement d'un projet. question très étroite notamment pour obtenir un argument dans un conflit avec un collègue (ou pour décider s'il vaut la peine de remanier le code). Pendant que la plupart des participants expérimentés essaient d'écrire une réponse, en gardant à l'esprit les points suivants la mission de Stack Overflow dans son ensemble, en faisant en sorte que leur réponse soit bonne pour le plus grand nombre de lecteurs possible, et pas seulement pour le PO.
15 votes
Si vous n'utilisez pas de paramètres, vous ne bénéficierez pas de la mise en cache des plans de requête, car il faudra créer un plan de requête distinct pour chaque nouvelle combinaison d'entrées que vous fournirez.
2 votes
Pensez-vous qu'une vérification est effectuée pour s'assurer que le nombre fourni qui est entré est validé pour s'assurer qu'il s'agit bien d'un nombre ?
0 votes
@ScottChamberlain La question porte sur la sécurité et non sur l'efficacité.
1 votes
@Tarik par paramètre je veux dire que je concatène un paramètre à une méthode dans laquelle je me trouve. Pensez-y,
public int QueryWhatever(int param)
, fortement typée.1 votes
Les risques de sécurité potentiels qui peuvent être corrigés en moins de temps qu'il n'en faut pour poser une question sur stackoverflow devraient être considérés comme des bogues... surtout lorsque la même correction améliore non seulement la sécurité et produit un code plus propre et plus facile à maintenir... mais aussi les performances. Normalement, vous devez sacrifier au moins un de ces 3 domaines.
6 votes
Comment savez-vous que ça prend moins de temps ? Cette situation se produit partout dans certains projets d'un développeur actuel et d'un développeur précédent. Si cela améliore réellement la sécurité, veuillez poster une réponse. Pour clarifier, je suis d'accord qu'il est préférable de paramétrer, évidemment. Mais ce n'est pas vraiment ma question.
0 votes
Parce que vous connaissez déjà le changement requis. Et c'est très facile de chercher sqlcommand.
0 votes
Pour ce qui est de la réponse, ma réponse serait la même que celle des autres ci-dessous. Il suffit de paramétrer les requêtes. Il est inutile de poster des réponses en double.
6 votes
@MatthewWhited Je ne voudrais pas que vous postiez une réponse en double. Si vous pouvez contribuer à quelque chose qui ajoute de la valeur et répond à ma question initiale, cependant, veuillez le faire. Quoi qu'il en soit, dire "il suffit de paramétrer les requêtes" ne répond pas à ma question initiale.
0 votes
Je n'arrive pas à comprendre quel type de pensée peut amener quelqu'un à poser une telle question - à moins que vous ne soyez dans un environnement où quelqu'un vous fait payer pour chaque utilisation d'un paramètre - ce n'est pas comme s'il y avait un problème inhérent à l'utilisation de ce paramètre. coût pour les utiliser.
7 votes
Les requêtes paramétrées sont principalement utilisées pour la performance et l'optimisation. La prévention des injections SQL est un effet secondaire.
14 votes
Je pense que le PO a posé une question valable. Il essaie d'évaluer le rapport coût/bénéfice de la correction d'un risque potentiel. Cette équation change avec le potentiel de ce risque. Si le risque est nul, je ne le ferais pas non plus. Il a demandé une question technique sur le potentiel, pas un jugement subjectif pour savoir si vous pensez que cela vaut la peine de perdre son temps. Le PO est le seul à pouvoir prendre cette décision.
10 votes
Pour m'expliquer : Je suis un DBA. J'apprécie et respecte les meilleures pratiques, et dans un monde parfait, tout le code serait parfait. Malheureusement, dans le monde dans lequel je travaille, j'ai plus de problèmes à résoudre que de temps pour le faire. Cela signifie qu'il faut établir des priorités. Réécrire du code qui fonctionne déjà, qui est sécurisé et qui a des performances acceptables, c'est un luxe. (Que je ne peux pas me permettre)
0 votes
@Peter, ça ressemble à la sécurité de l'emploi pour moi. Honnêtement, il semble que la vulnérabilité n'est pas vraiment là si les fonctions sont correctement gated pour commencer. Si ce n'est pas le cas, je suggérerais de localiser chaque instance qui n'est pas correctement paramétrée ou d'implémenter un contrôle approprié via une sorte de palliatif global (probablement propagé avec regex). Sinon, un outil merveilleux à utiliser pour localiser du code spécifique par environ 50 paramètres optionnels différents est Agent Ransack . Cette beauté passe au crible des gigaoctets de code en quelques secondes.
4 votes
Je vois des réponses qui disent que ce n'est pas sûr parce que quelqu'un peut changer les formats de culture. De cette façon, c'est comme si nous disions que quelqu'un peut changer notre code ! ou que quelqu'un peut changer les paramètres du serveur. Dans la plupart des cas, si quelqu'un peut changer les paramètres du serveur ou peut injecter du code dans votre application, il semble que l'ensemble du serveur ne soit pas sécurisé. La personne qui peut injecter du code dans votre application ou qui peut changer les paramètres du serveur, elle n'a pas besoin d'attaques par injection SQL !
2 votes
Qui peut modifier les paramètres du serveur ou qui peut exécuter un tel code pour changer la culture ? Si une personne peut le faire dans votre serveur, elle n'a pas besoin d'une injection SQL pour détruire des données.
0 votes
Vous pouvez au moins remplacer ' par '', c'est un peu plus sûr, pour échapper au caractère ''.