Peut instruction paramétrée arrêter tous les injection SQL?
Si oui, pourquoi il y a encore beaucoup de succès à des injections SQL? Juste parce que certains développeurs sont trop con pour utiliser les instructions paramétrées?
- C'est une grande question, avec absolument terrible réponses (comme le temps, je suis commentaires)
- Je souhaite que quelqu'un avec une bonne 15k à la réputation ou au moins avec une bonne expérience pouvez ajouter une contribution précieuse à cette question.
- Voir projet de Loi Karwin de l' Sql Injection Mythes et idées fausses parler et diapositives pour plus d'informations sur ce sujet. Il explique ce que l'injection SQL est, comment échapper n'est généralement pas assez bon, et comment les procédures stockées et de paramétrer des déclarations peut être compromise.
- Voir certains projet de Loi Karwin de l' des réponses à des questions similaires: qu'est-Ce que l'injection SQL?
Vous devez vous connecter pour publier un commentaire.
Les liens que j'ai posté dans mes commentaires à la question d'expliquer le problème très bien. Je viens de résumer mes sentiments sur les raisons pour lesquelles le problème persiste, ci-dessous:
Ceux qui commencent tout juste peut avoir aucune conscience de l'injection SQL.
Certains sont conscients de l'injection SQL, mais pense que l'évitement est la (seule?) solution. Si vous faites une recherche rapide sur Google pour
php mysql query
, la première page qui s'affiche est lemysql_query
page, sur laquelle il y a un exemple qui montre l'interpolation échappé à la saisie de l'utilisateur dans une requête. Il n'y a pas de mention (au moins pas ce que je peux voir) de l'utilisation des requêtes préparées à la place. Comme d'autres l'ont dit, il ya tellement de nombreux tutoriels qui utiliser le paramètre d'interpolation, que ce n'est pas vraiment surprenant de constater que c'est encore souvent utilisé.Un manque de compréhension de la façon dont les instructions paramétrées travail. Certains pensent que c'est juste une fantaisie moyen d'échapper à des valeurs.
D'autres sont conscients des instructions paramétrées, mais ne les utilisent pas parce qu'ils ont entendu dire qu'ils sont trop lents. Je soupçonne que beaucoup de gens ont entendu comment incroyablement lent paramterized consolidés sont, mais n'ont pas fait de test de leur propre. Comme le projet de Loi Karwin l'a souligné dans son discours, la différence de performance est rarement utilisé comme un facteur lorsque l'on examine l'utilisation des requêtes préparées. Les avantages de préparer une fois, exécuter de nombreuses, semblent souvent être oublié, de même que les améliorations dans la sécurité et la maintenabilité du code.
Certains utilisent des instructions paramétrées partout, mais avec interpolation des valeurs non vérifiées, tels que des tables et des colonnes de noms, mots-clés et les opérateurs conditionnels. Des recherches dynamiques, tels que ceux qui permettent aux utilisateurs de spécifier un certain nombre de différents champs de recherche, de faire une comparaison des conditions et l'ordre de tri, sont d'excellents exemples de cette.
Faux sentiment de sécurité lors de l'utilisation d'un ORM. Orm permettent encore d'interpolation de l'instruction SQL pièces - voir 5.
De programmation est un sujet vaste et complexe, gestion de base de données est un sujet vaste et complexe, la sécurité est un sujet vaste et complexe. Le développement d'une base de données sécurisée de l'application n'est pas facile - même les développeurs expérimentés peuvent se faire attraper.
Beaucoup de réponses sur stackoverflow n'aident pas. Quand les gens écrivent des questions que l'utilisation du SQL dynamique et les paramètres d'interpolation, il y a souvent un manque de réponses qui suggèrent à l'aide des instructions paramétrées à la place. A quelques reprises, j'ai eu des gens de réfuter ma suggestion: utiliser les requêtes préparées, généralement en raison de la perception de l'inacceptable sur les performances système. Je doute sérieusement que ceux qui demandent la plupart de ces questions sont dans une position où le supplément de quelques millisecondes de préparation d'une instruction paramétrée aura un effet catastrophique sur leur application.
Lorsque les articles parlent des requêtes paramétrées arrêt de SQL attaques, ils n'ont pas vraiment expliquer pourquoi, c'est souvent une affaire de "Il ne, alors ne me demandez pas pourquoi" - peut-être parce qu'ils ne savent pas eux-mêmes. Un signe certain d'un mauvais éducateur est celui qui ne peut pas admettre qu'ils ne savent pas quelque chose. Mais je m'égare.
Quand je dis que je l'ai trouvé tout à fait compréhensible être confondu est simple. Imaginez une dynamique de requêtes SQL
une simple injection sql serait juste de mettre le nom d'utilisateur en tant que ' or 1=1--
Cela permettrait effectivement de faire la requête sql:
Cela dit sélectionnez tous les clients là où ils sont le nom d'utilisateur est vide ( "" ) ou 1=1, ce qui est un booléen, soit vrai. Ensuite, il utilise -- pour commenter le reste de la requête. Donc cela il suffit d'imprimer tous les clients de la table, ou faire ce que vous voulez avec elle, si la connexion, il va se connecter avec la première privilèges de l'utilisateur, qui peut souvent être l'administrateur.
Maintenant des requêtes paramétrées le faire différemment, avec un code comme:
où nom d'utilisateur et mot de passe sont des variables pointant à la saisie de nom d'utilisateur et le mot de passe
Maintenant, à ce stade, vous pensez peut-être, cela ne changera rien du tout. Sûrement, vous pouvez toujours juste de la mettre dans le champ nom d'utilisateur, quelque chose comme Personne OU 1=1'--, ce qui fait la requête:
Et cela semble comme un argument valable. Mais, vous avez tort.
La façon dont les requêtes paramétrées travail, c'est que le sqlQuery est envoyé sous la forme d'une requête et de la base de données sait exactement ce que cette requête va le faire, et alors seulement, il insérez le nom d'utilisateur et mots de passe simplement en tant que valeurs. Cela signifie qu'ils ne peuvent pas l'effet de la requête parce que la base de données, on sait déjà ce que la requête ne pourra le faire. Donc, dans ce cas, il aurait l'air d'un nom d'utilisateur de "Personne OU 1=1'--" et un mot de passe vide, qui doit venir de faux.
Cette solution n'est pas complète si, et de validation de la saisie aura encore besoin d'être fait, car ce ne sera pas pour effet d'autres problèmes, tels que les attaques XSS, comme vous avez pu encore mettre du code javascript dans la base de données. Alors si c'est de lire sur une page, il affiche normalement javascript, selon toute validation de sortie. Si vraiment la meilleure chose à faire est de toujours utiliser la validation de l'entrée, mais à l'aide de requêtes paramétrées ou des procédures stockées pour stopper toutes les attaques SQL.
Bien bonne question.
La réponse est plus déterministe et stochastique que je vais essayer d'expliquer mon point de vue, à l'aide d'un petit exemple.
Il y a de nombreuses références sur le net qui nous suggérer d'utiliser des paramètres à nos demandes d'information ou d'utiliser une procédure stockée avec des paramètres afin d'éviter l'Injection SQL (SQLi). Je vais vous montrer que des procédures stockées (par exemple) n'est pas la baguette magique contre SQLi. La responsabilité reste encore sur le programmeur.
De considérer les éléments suivants Procédure Stockée SQL Server qui vous permettra d'obtenir la ligne d'utilisateur à partir d'une table "Utilisateurs":
Vous pouvez obtenir les résultats en passant comme paramètres le nom d'utilisateur et le mot de passe. En supposant que le mot de passe en texte libre (seulement pour des raisons de simplicité de cet exemple) d'un appel normal serait:
Mais ici nous avons une mauvaise technique de programmation utilisé par le programmeur à l'intérieur de la procédure stockée, de sorte qu'un attaquant peut exécuter les opérations suivantes:
Les paramètres ci-dessus seront passées en arguments à la procédure stockée et la commande SQL qui finalement sera exécutée est:
..ce qui permettra d'obtenir toutes les lignes arrière des utilisateurs
Le problème ici est que nous avons tout de même suivre le principe de "Créer une procédure stockée et transmettre les champs de recherche que les paramètres de" la SQLi est toujours pratiquée. C'est parce que nous venons de copier notre mauvaise programmation de la pratique à l'intérieur de la procédure stockée. La solution de ce problème consiste à réécrire notre Procédure Stockée comme suit:
Ce que j'essaie de dire, c'est que les développeurs doivent apprendre d'abord ce qu'est un SQLi attaque est et comment peut être effectué et pour la sauvegarde de leur code en conséquence. Suivant aveuglément les "meilleures pratiques" n'est pas toujours la manière la plus sécuritaire... et c'est peut-être pourquoi nous avons tant de "bonnes pratiques" - ne!
Oui, l'utilisation des requêtes préparées arrête toutes les injections SQL, au moins en théorie. Dans la pratique, les instructions paramétrées peuvent ne pas être réel préparées, par exemple,
PDO
en PHP émule par défaut donc c'est ouvert à un bord d'attaque.Si vous êtes en utilisant de vraies déclarations préparées à l'avance, tout est sûre. Eh bien, au moins aussi longtemps que vous n'avez pas concaténer dangereux SQL dans votre requête comme une réaction pour ne pas être en mesure de préparer des noms de table par exemple.
Oui, l'éducation est le point principal ici, et l'héritage des bases de code. De nombreux tutoriels d'utilisation de fuir et ceux qui ne peuvent pas être facilement retiré du web, malheureusement.
- Je éviter absolus dans la programmation, il y a toujours une exception. Je recommande fortement les procédures stockées et les objets de commande. La majorité de mon arrière du terrain est avec SQL Server, mais je ne joue qu'avec MySql à partir de temps à autre. Il existe de nombreux avantages pour les procédures stockées, y compris la mise en cache des plans de requête; oui, cela peut être accompli avec des paramètres et dans la ligne de SQL, mais qui ouvre plus de possibilités pour les attaques par injection et n'aide pas à la séparation des préoccupations. Pour moi, il est aussi beaucoup plus facile à sécuriser une base de données que mes applications n'ont généralement autorisation d'exécution de ladite procédures stockées. Sans direct de table/vue de l'accès, il est beaucoup plus difficile à injecter quoi que ce soit. Si les applications de l'utilisateur est compromis, on n'a l'autorisation d'exécuter exactement ce qui a été pré-définis.
Mes deux cents.
Je ne dirais pas "stupide".
Je pense que les tutos sont le problème. La plupart SQL tutoriels, livres, quelle que soit expliquer SQL avec inline valeurs, de ne pas mentionner lier des paramètres à tous. L'apprentissage de ces tutoriels n'ont pas la possibilité d'apprendre le droit.
Parce que la plupart de code n'est pas écrit en pensant à la sécurité, et la gestion, le choix entre l'ajout de fonctionnalités (en particulier quelque chose de visible, qui peuvent être vendus) et de la sécurité, de la stabilité et de la fiabilité (qui est beaucoup plus difficile de vendre), ils seront presque toujours choisir la première. La sécurité est un sujet de préoccupation seulement quand il devient un problème.
Oui, aussi longtemps que votre pilote de base de données offre un espace réservé pour tous les possible de SQL littérale. La plupart de préparation des pilotes n'en ont pas. Dites, vous n'auriez jamais trouver un espace réservé pour un nom de champ ou pour un tableau de valeurs. Qui va faire un développeur de retomber dans l'adaptation d'une requête à la main, à l'aide de la concaténation et la mise en forme manuelle. Avec les résultats prévus.
C'est pourquoi j'ai fait mon Mysql wrapper pour PHP qui prend en charge la plupart des littéraux, qui peuvent être ajoutés à la requête dynamiquement, y compris les tableaux et les identificateurs.
Comme vous pouvez le voir, en réalité, il est juste impossible d'avoir tous vos requêtes paramétrées, même si vous n'êtes pas stupide.
Tout d'abord, ma réponse à votre première question: Oui, autant que je sache, en utilisant des requêtes paramétrées, injections SQL ne sera plus possible. Quant à vos questions ci-dessous, je ne suis pas sûr et ne peut que vous donner mon opinion sur les raisons:
Je pense qu'il est plus facile de "juste" écriture de la chaîne de requête SQL par concaténer les différentes parties (peut-être même dépendant de certains contrôles logiques) ainsi que les valeurs à insérer.
C'est juste de la création de la requête et de l'exécuter.
Un autre avantage est que vous pouvez imprimer (echo, de sortie ou quoi que ce soit) la chaîne de requête sql et ensuite utiliser cette chaîne pour un manuel de requête du moteur de base de données.
Lorsque vous travaillez avec des déclarations préparées à l'avance, vous avez toujours au moins une étape de plus:
Vous devez construire votre requête (y compris les paramètres, bien sûr)
Vous avez à vous préparer à la requête sur le serveur
Vous devez lier les paramètres pour les valeurs réelles que vous souhaitez utiliser pour votre requête
Vous devez exécuter la requête.
Qui est un peu plus de travail (et pas si simple à programmer), en particulier pour certains "rapide et sale" des emplois qui se révèlent souvent être de très longue durée de vie...
Cordialement,
Boîte de
Pour protéger votre application contre l'injection SQL, exécutez les étapes suivantes:
L'étape 1. Limiter l'entrée.
Étape 2. Utilisez les paramètres avec des procédures stockées.
Étape 3. Utilisez les paramètres avec le SQL dynamique.
Reportez-vous à http://msdn.microsoft.com/en-us/library/ff648339.aspx
Injection SQL est un sous-ensemble du problème de l'injection de code, où les données et le code sont fournis sur le même canal et de données est pris pour le code. Les requêtes paramétrées empêcher que cela se produise par la formation de la requête à l'aide de contexte sur ce qui est des données et quel est le code.
Dans certains cas précis, ce n'est pas suffisant. Dans de nombreux DBMSes, il est possible d'exécuter dynamiquement SQL avec des procédures stockées, l'introduction d'une faille de SQL injection au SGBD niveau. Appel d'une telle procédure stockée à l'aide de requêtes paramétrées ne va pas empêcher l'injection SQL dans la procédure à partir de l'exploitation. Un autre exemple peut être vu dans ce blog.
Le plus souvent, les développeurs utilisent la fonctionnalité de manière incorrecte. Souvent, le code ressemble à ceci une fois fait correctement:
Certains développeurs concaténer des chaînes, puis utiliser une requête paramétrée, ce qui n'est pas réellement faire de données ci-dessus/code distinction qui offre les garanties de sécurité que nous recherchons:
La bonne utilisation de requêtes paramétrées offre très fort, mais pas impénétrable, la protection contre les attaques par injection SQL.
même si
les requêtes préparées sont correctement utilisés tout au long de la web application
code, de failles d'injection SQL peut encore exister que si la base de données des composants de code de construire
des requêtes à partir de la saisie de l'utilisateur d'une manière dangereuse.
L'exemple suivant est un exemple d'une procédure stockée qui est vulnérable à SQL
l'injection dans le @nom de paramètre:
Même si l'application passe fourni par l'utilisateur nom de la valeur à la stockées
procédure d'une manière sûre, la procédure elle-même concatène ceci directement dans
une requête dynamique et est donc vulnérable.