Comment peut-assainissement qui s'échappe des apostrophes être vaincu par injection SQL dans SQL Server?
Pour amorcer ce processus, je suis bien conscient que les requêtes paramétrées sont la meilleure option, mais je me demande ce qui rend la stratégie que je présente ci-dessous vulnérables. Les gens insistent ci-dessous la solution ne fonctionne pas, donc je suis de regarder pour un exemple de pourquoi il ne serait pas.
Si le SQL dynamique est construit dans le code à l'aide de la suite à s'échapper avant d'être envoyé à un Serveur SQL server, ce type d'injection peut vaincre ce?
string userInput= "N'" + userInput.Replace("'", "''") + "'"
Une question semblable a été répondu ici, mais je ne crois pas que les réponses sont ici applicables.
Échapper l'apostrophe avec un "\" n'est pas possible dans SQL Server.
Je crois SQL Contrebande avec Unicode (décrites ici) serait contrarié par le fait que la chaîne est produit est marqué comme Unicode par le N précédant l'apostrophe. Autant que je sache, il n'y a pas d'autres jeux de caractères SQL Server traduirait automatiquement à un seul devis. Sans non échappés apostrophe, je ne crois pas que l'injection est possible.
Je ne crois pas la Troncature de Chaîne est viable vecteur soit. SQL Server ne sera certainement pas faire la troncature depuis la taille maximale pour un nvarchar
est de 2 go selon microsoft. 2 GO de chaîne est impossible dans la plupart des situations, et de l'impossible dans la mienne.
Second Ordre Injection pourrait être possible, mais est-il possible si:
- Toutes les données dans la base de données est désinfecté à l'aide de la méthode ci-dessus
- Valeurs de la base de données ne sont jamais ajouté SQL dynamique (pourquoi vous le faites jamais de toute façon, quand vous pouvez simplement référence à la valeur de la table dans la partie statique de toute chaîne SQL dynamique?).
Je ne dis pas que c'est mieux que la ou une alternative à l'utilisation de requêtes paramétrées, mais je veux savoir comment ce que j'ai décrit est vulnérable. Des idées?
- Pas de. Vous êtes toujours sensible aux attaques de la forme:
"SELECT * FROM MyTable WHERE Field = " + userInput
quanduserInput
est0; DROP TABLE OhNo;
. - Cela n'a aucun sens. Dans l'exemple ci-dessus, votre entrée utilisateur serait aseptisé pour N'0; DROP TABLE OhNo;' avant même d'être exécuté.
- Si pour l'assainissement des variables de chaîne seulement. Des choses comme "int" n'ont pas besoin d'être désinfectés s'ils sont exprimés comme un int avant d'être ajoutés à la requête. Peu importe, je ne demande qu'à propos de la désinfection des chaînes de la droite maintenant. Aussi, il n'est pas nécessaire impoli ici. Si vous pouvez penser à un moyen que ce n'est pas sûr, j'aimerais savoir.
- Ok, comment sur userinput = "test"; drop table ohno; print""
- Le seul quores sont transformés en deux guillemets simples (c'est comment vous échapper les guillemets simples), renderign inoffensifs. Votre saisie de l'utilisateur devient alors: N'test"; drop table ohno; print " qui est inoffensif
- Pas une question intéressante qu'il y a zéro avantages de votre approche vs aide d'une requête paramétrée. Il y a plusieurs inconvénients incluent excessive des compilations et plan de cache de la météorisation.
- Aussi, si la colonne de la table n'est pas unicode, vous allez empêcher l'utilisation des index sur les colonnes en raison de la conversion implicite.
- Il n'y a absolument pas de scénario où il vous serait en mesure de faire de l'entrée de l'assainissement, et de ne pas être capable d'écrire de la requête paramétrée. Si vous en savez assez sur schéma de base de données pour être en mesure de vérifier les entrées vous-même, alors vous en savez assez pour écrire paramétrées requête. Choix évident est paramétrisée requête parce que résultant code sera plus propre, moins sujettes à des erreurs et accidentelle des problèmes de sécurité lorsque le code responsable n'est pas prudent.
- Ne serait-ce pas un bon choix lorsque le SQL dynamique est inévitable?
- Il y a des raisons quand littéral de l'analyse est nécessaire. Imaginez que vous êtes le traitement d'une liste de chaînes de caractères de longueur inconnue et la nécessité de générer une instruction SQL à faire: SELECT x à partir de y où le texte dans ('A', 'B', 'C', ...) La seule façon d'écrire cette déclaration dynamiquement et de manière efficace avec des littéraux. GBleaney de la méthode est sûre, on dirait qu'il est écrit de code C# qui est en unicode, le .Net pilote unicode et il n'y a rien de mal à cela.
- Je peux toujours créer le sql avec la nécessaire ? pour les paramètres et fournir les paramètres séparément. Surtout depuis que je dois faire certaine analyse de toute façon puisque la longueur d'un "à la" clause est limitée dans de nombreux SGBDR.
- Oui, vous pouvez créer une dynamique de chaîne de requête et de la place des marqueurs de paramètres au lieu de littéraux.
- C'est une question intéressante lorsque le code en question est de plus de 25 ans et difficiles à rénover avec des requêtes paramétrées.
Vous devez vous connecter pour publier un commentaire.
Il y a quelques cas où cette fuite en fonction échouera. Le plus évident est que lorsqu'une seule citation n'est pas utilisé:
Dans ce cas, vous pouvez "sortir" à l'aide d'un double-quote, un arrière-tique. Dans le dernier cas, il n'y a rien à "sortir", de sorte que vous pouvez simplement écrire
1 union select password from users--
ou quoi que sql charge l'attaquant désirs.La condition suivante où cette fuite en fonction échouera si une sous-chaîne est pris après que la chaîne est échappé (et oui j'ai trouvé des vulnérabilités comme ça dans la nature):
Dans ce cas, un nom d'utilisateur de
abcdefgji'
sera transformé enabcdefgji''
par la fonction d'échappement, puis se retourna enabcdefgji'
par la prise de la sous-chaîne. Cela peut être exploité par le réglage de la valeur du mot de passe de n'importe quelle instruction sql, dans ce casor 1=1--
serait interprété comme sql et le nom d'utilisateur serait interprété commeabcdefgji'' and password=
. La requête est comme suit:T-SQL et d'autres fonctions de sql injection des techniques déjà mentionnées. Avancé d'Injection SQL Dans SQL Server Applications est un grand livre que vous devez lire si vous ne l'avez pas déjà.
La question finale est de l'unicode des attaques. Cette classe de vulnérabilités se pose parce que la fonction d'échappement n'est pas au courant de l'encodage multi-octet, ce qui peut être utilisé par un attaquant pour "consommer" le caractère d'échappement. Ajoutant un "N" à la chaîne ne va pas aider, car cela n'affecte pas la valeur de multi-octets caractères plus tard dans la chaîne. Cependant, ce type d'attaque est très rare car la base de données doit être configuré pour accepter GBK des chaînes unicode (et je ne suis pas sûr que MS-SQL peut le faire).
De Second Ordre de l'injection de code est encore possible, cette attaque motif est créé par la confiance contrôlé par l'attaquant des sources de données. L'échappement est utilisé pour représenter les caractères de contrôle que leur caractère littéral. Si le développeur oublie d'échapper à une valeur obtenue à partir d'un
select
et utilise ensuite cette valeur dans une autre requête, puis bam l'attaquant aura un caractère littéral de devis unique à leur disposition.Tout tester, la confiance rien.
'
comme délimiteur de chaîne. À l'aide de tique ou le guillemet double ne serait pas aider à l'attaquantAvec certaines autres dispositions, votre approche ci-dessus n'est pas vulnérable à une injection SQL. Le principal vecteur d'attaque à considérer est SQL de la Contrebande. SQL Contrebande se produit lorsque similaire pour les caractères unicode sont traduits de manière inattendue (par exemple, ` modification ' ). Il y a plusieurs endroits où une pile d'application pourraient être vulnérables à SQL Contrebande.
Le langage de Programmation de manipuler des chaînes unicode de manière appropriée? Si la langue n'est pas conscient unicode, il peut mal identifier un octet dans un caractère unicode comme un seul devis et de s'en échapper.
Le client de base de données de la bibliothèque (par exemple, ODBC, etc) poignée de chaînes unicode de manière appropriée? Système.Les données.SqlClient dans le .Net framework n', mais comment sur les anciennes bibliothèques de windows 95 à l'époque? Troisième partie ODBC bibliothèques existent. Qu'advient-il si le pilote ODBC ne prend pas en charge unicode dans la chaîne de requête?
La DB gérer l'entrée correctement? Les versions modernes de SQL sont à l'abri en supposant que vous êtes en utilisant N", mais qu'en SQL 6.5? SQL 7.0? Je ne suis pas au courant de toutes les vulnérabilités particulières, cependant ce n'était pas sur le radar pour les développeurs dans les années 1990.
Dépassements de la mémoire tampon? Une autre préoccupation est que la chaîne est plus longue que la chaîne d'origine. Dans la version de Sql Server est la limite de 2 go pour l'entrée introduit? Avant que ce qui était à la limite? Sur les anciennes versions de SQL, ce qui s'est passé lorsqu'une requête a dépassé la limite? Ne tout il existe des limites sur la durée d'une requête à partir du point de vue de la bibliothèque de réseau? Ou sur la longueur de la chaîne dans le langage de programmation?
Il n'existe aucun langage des paramètres qui affectent la comparaison utilisée dans la fonction de remplacement ()? .Net toujours fait une comparaison binaire de la fonction de remplacement (). Sera toujours le cas? Ce qui se passe si une version plus récente .NET prend en charge primordial que le comportement à l'application.config niveau? Que faire si nous avons utilisé une regexp au lieu de Remplacer les() pour insérer un guillemet simple? L'ordinateur, les paramètres régionaux affectent cette comparaison? Si un changement dans le comportement a eu lieu, il pourrait ne pas être vulnérable à l'injection sql, cependant, il peut, par inadvertance, a édité la chaîne par la modification d'une uni-caractère de code qui ressemblait à une seule offre dans un seul devis avant il n'a jamais atteint la DB.
Donc, en supposant que vous utilisez le Système.Chaîne de caractères.Fonction de remplacement() en C# sur la version actuelle de .Net avec le haut-SqlClient bibliothèque à contre courant (2005-2012) version de SQL server, puis votre approche n'est pas vulnérable. Comme vous commencer à changer les choses, alors aucune promesse ne peut être faite. La requête paramétrée approche est la bonne approche pour l'efficacité, de performance, et (dans certains cas) pour plus de sécurité.
AVERTISSEMENT Les commentaires ci-dessus ne sont pas une approbation de cette technique. Il ya plusieurs autres très bonnes raisons à cela la mauvaise approche pour la génération de SQL. Cependant, détaillant est en dehors de la portée de cette question.
NE PAS UTILISER CETTE TECHNIQUE POUR LES NOUVEAUX DÉVELOPPEMENTS.
NE PAS UTILISER CETTE TECHNIQUE POUR LES NOUVEAUX DÉVELOPPEMENTS.
NE PAS UTILISER CETTE TECHNIQUE POUR LES NOUVEAUX DÉVELOPPEMENTS.
CREATE LOGIN
dans le développement de nouvelles?En utilisant les paramètres de la requête est mieux, plus facile, et plus rapide que d'échapper les guillemets.
Re de votre commentaire, je vois que vous avez reconnu le paramétrage, mais il mérite d'être soulignée. Pourquoi voudriez-vous d'utiliser échapper lorsque vous pouvez paramétrer?
Dans Avancé d'Injection SQL Dans SQL Server Applications, recherche pour le mot "remplacer" dans le texte, et de ce point sur la lecture des exemples où des développeurs, par inadvertance, a permis des attaques par injection SQL, même après avoir échappé à la saisie de l'utilisateur.
Il y a un cas limite où s'échapper les guillemets avec
\
résultats dans un état de vulnérabilité, car le\
devient la moitié d'un permis de caractères multi-octets dans certains jeux de caractères. Mais ce n'est pas applicable à votre cas puisque\
n'est pas l'échappement de caractères.Comme d'autres l'ont souligné, vous pouvez aussi ajouter du contenu dynamique à votre SQL pour autre chose qu'une chaîne de caractères littérale ou littéral de date. De Table ou de colonne des identifiants sont délimités par des
"
en SQL, ou[
]
dans Microsoft/Sybase. Mots-clés SQL de cours n'ont pas de délimiteurs. Pour ces cas, je vous recommande de liste blanche les valeurs à interpoler.Ligne de fond est que l'évitement est une défense efficace, si vous pouvez vous assurer que vous faire de manière cohérente. C'est le risque: celui de l'équipe de développeurs sur votre demande pourrait omettre une étape et faire de la chaîne d'interpolation mal.
Bien sûr, la même chose est vraie pour les autres méthodes, comme la paramétrisation. Ils ne sont efficaces que si vous le faites de manière cohérente. Mais je trouve que c'est plus facile à la plus rapide d'utiliser les paramètres, que de trouver le bon type de s'échapper. Et les développeurs sont plus susceptibles d'utiliser une méthode qui est pratique et ne pas les ralentir.
SQL injection se produire si l'utilisateur a fourni des intrants sont interprétées comme des commandes. Ici, la commande s'entend de tout ce qui n'est pas interprété comme un type de données littérale.
Maintenant, si vous êtes à l'aide de la saisie de l'utilisateur que dans les données littérales, spécialement dans les littéraux de chaîne, la saisie de l'utilisateur ne serait interprété comme quelque chose de différent de la chaîne de données si elle serait en mesure de quitter la chaîne de caractères littérale contexte. Pour la chaîne de caractères Unicode ou des littéraux de chaîne, c'est le guillemet simple qui entoure les données littérales tout intégré guillemet simple besoin d'être représenté avec deux guillemets simples.
Laisser un littéral de chaîne contexte, il serait nécessaire de fournir un seul guillemet simple (sic) que les deux guillemets simples sont interprétés comme une chaîne de caractères littérale de données et non pas comme une chaîne littérale délimiteur de fin.
Donc, si vous êtes en remplacement de toutes les guillemet simple dans les données fournies par les utilisateurs par deux guillemets simples, il sera impossible pour l'utilisateur de quitter la chaîne de caractères littérale contexte.
SQL Injection peut se faire par unicode. Si l'application web a une URL comme ceci:
http://mywebapp/widgets/?Code=ABC
qui génère le SQL comme
sélectionnez * à partir de widgets, là où le Code = 'ABC'
mais un hacker entre dans ce:
http://mywebapp/widgets/?Code=ABC%CA%BC;drop table des widgets--
SQL va ressembler
sélectionnez * à partir de widgets, là où le Code = 'ABC’;drop table des widgets--'
et SQL Serveur va exécuter deux Instructions SQL. Pour faire la sélection et à la baisse.
Votre code probablement convertit l'url-encodé %CA%colombie-britannique en unicode U02BC qui est un "Modificateur de lettre apostrophe". La fonction replace dans .Net ne sera PAS traiter que comme une seule citation. Cependant Microsoft SQL Server traite comme un seul devis. Voici un exemple qui permettra probablement d'Injection SQL:
Il n'est probablement pas 100% sûre façon, si vous faites de concaténation de chaîne. Ce que vous pouvez faire est d'essayer de vérifier le type de données pour chaque paramètre et si tous les paramètres de passer cette validation puis aller de l'avant avec l'exécution. Par exemple, si votre paramètre doit être de type int, et vous obtenez quelque chose qui ne peut pas être converti en int puis il suffit de le rejeter.
Cela ne fonctionne pas, mais si vous êtes en acceptant de type nvarchar paramètres.
Comme d'autres l'ont signalé. La manière la plus sûre est d'utiliser des requêtes paramétrées.