6
votes

Mes utilisateurs peuvent-ils injecter mon SQL dynamique?

Je suis un développeur de bureau écriture pour les utilisateurs internes, donc je ne suis pas inquiet pour les pirates malveillants, mais j'aimerais savoir s'il y a tout ce qui pourrait entrer lors de la mise à jour d'une valeur qui exécuterait SQL sur le serveur.

L'entreprise définit leur schéma de contenu et j'ai une demande de CRUD pour eux qui ne doit pas être modifiée lorsque leur schéma change, car les détails de la validation sont axés sur table et que les mises à jour sont avec Dynamic SQL. Je dois prendre en charge des guillemets simples dans leur entrée de données, alors quand ils les entrent, je les doublons avant que le SQL soit exécuté sur le serveur. De ce que j'ai lu, cependant, cela ne devrait pas suffire à arrêter une injection.

Donc, ma question est de savoir quel texte pourrait-il entrer dans un champ de texte libre qui pourrait changer quelque chose sur le Serveur au lieu d'être stocké comme une valeur littérale?

Fondamentalement, je construisez une instruction SQL au moment de l'exécution qui suit le modèle SUPPORT:

MISE À JOUR FILE DE SET FILE = VALEUR OU PKFIELD = PKVAL

avec ce code vb.net: xxx

Lorsque je mettez à jour un champ de texte à la valeur

Redmond '; Table de goutte ordettable -

il génère: xxx

et met à jour la valeur à la valeur littérale qu'ils ont entrée.

Quoi d'autre pourrait-il entrer INJECT SQL?

Encore une fois, je ne suis pas inquiet que quelqu'un veuille pirater le serveur à leur travail, mais j'aimerais savoir comment s'ils pouvaient coller accidentellement un texte d'ailleurs et casser quelque chose.

merci.


8 commentaires

"Je ne suis pas inquiet que quelqu'un veuille pirater le serveur à leur travail" - vous feriez mieux d'être, des employés mécontents font de jolis nuisides attaquants.


Si vous en étiez un, quel SQL utiliseriez-vous?


+1 pour une bonne question. C'est quelque chose que je me suis demandé de moi-même. J'ai vu beaucoup d'affirmations vagues dans des livres de texte à ce sujet d'être insuffisante mais jamais d'explication pourquoi. Je serais ravi que quelqu'un puisse répondre correctement avec un exemple définitif de saisie de l'utilisateur qui causerait un problème. Je suis prêt à parier maintenant que cela ne va pas arriver et compléter les non-réponses qui ne traitent pas de la question très spécifique recommandant SQL paramétrice sera votée au sommet.


Changer de guillemets simples sur des citations simples doublées peut être très bien pour VB.NET, mais lorsque Beth utilise une autre langue, cela pourrait ne pas fonctionner correctement. Il est préférable d'avoir l'habitude d'écrire un code approprié d'injection à l'aide de SQL paramétré au lieu d'écrire un code de nettoyage d'entrée spécifique à la langue. Tout ce qu'il faut, c'est oublier d'échapper à quelque chose une fois, et vos tables viennent d'être chutées. Beth se demande s'il y a eu d'autres intrants pouvant être utilisés pour pirater sa base de données. Avec SQL paramétrée, elle n'a pas à se demander.


@Canspice - Je comprends votre point, mais il y a des circonstances dans lesquelles SQL dynamique à travers une concaténation à la chaîne est inévitable. Tout dans SQL peut être paramétré. Pour ces circonstances, il est important que nous comprenons pourquoi quelque chose n'est pas en sécurité, nous comprenons donc et peut atténuer les risques.


@Canspice, à partir de ce que j'ai lu, SQL paramétrice est plus sûr, mais pas de balle. J'ai lu que l'utilisation de cette approche n'est pas suffisamment sûre. Peut-être que c'est spécifique à la langue? MS ne veut pas que les développeurs écrivent un code facilement piraté, ils ont donc des messages indiquant que rien sur le Web n'est en sécurité des pirates motivés. Je suis d'accord. Je ne développe pas pour le Web. Dans quelle mesure ces règles s'appliquent-elles à moi? Seulement si je reste sur le bureau avec des utilisateurs authentifiés internes?


Eh bien, vous ne devriez jamais faire confiance à vos utilisateurs, peu importe qui ils sont. Vous ne savez pas qui le prochain employé mécontent sera à votre entreprise. Intranet ou Internet, peu importe. Que se passe-t-il si votre entreprise décide de libérer ce produit sur le Web? Ou si l'un de vos collègues dit: "Hé, Beth a fait ce site génial, je vais utiliser une partie du code de mon projet sur le Web"?


Si quelqu'un d'autre veut rejeter une approche SQL dynamique pour son projet, je n'ai aucun problème avec cela. Cela fonctionne pour moi et je vois les avantages et les risques sont assez peu probables que je suis satisfait de l'approche. Si quelqu'un d'autre veut le réécrire sans SQL dynamique, c'est bien, cela leur prendra simplement plus de ressources pour maintenir. Lorsque le schéma de contenu de l'entreprise change, je ne change pas de code source, je modifie les données dans les tables. Vraiment pas cher.


6 Réponses :


1
votes

En supposant que vous échappez à des littéraux strings (qui de ce que vous avez dit vous disiez), vous devriez être en sécurité. La seule autre chose que je peux penser, c'est que si vous utilisez un caractère basé sur unicode défini pour communiquer avec la base de données, assurez-vous que les chaînes que vous envoyez sont valables dans ce codage.


3 commentaires

Pouvez-vous me donner un exemple de chaîne non valide que je peux essayer de coller dans ma zone de texte?


Si j'essaie de poster une chaîne non valide ici, il est susceptible d'être corrigé par le site afin que UTF-8 non valide ne soit pas stocké dans la base de données de Stackoverflow. Donc, je peux vous fournir une recette pour une chaîne non valide, mais je ne peux pas réellement poster une. Il existe de multiples façons dans lesquelles une séquence d'octets peut ne pas être valide UTF-8; Voir Le "rel =" NOFOOL NOREFERRER "> EN.Wikipedia.org/wiki/utf-8"> La page Wikipedia . Par exemple, une valeur d'octets de 254 ou 255 ne peut pas apparaître dans UTF-8 valide.


Les erreurs de codage que vous devriez probablement être la plus préoccupée des caractères ASCII, telles que la séquence d'octets (192, 166) (qui est un codage supérieur d'une citation unique).



1
votes

Comme laidly que votre code de doublage est (: P - essayez String. Remplacez à la place.) Je suis sûr que cela fera le travail.


1 commentaires

Oui, ça marche très bien. Je continue d'entendre comment vous ne devriez jamais utiliser SQL dynamique et souhaitera mieux comprendre pourquoi, si je gère le cas évident. J'ai lu que la manipulation de cette affaire n'est pas suffisante, mais pas vu l'exemple montrant pourquoi.



1
votes

La seule hypothèse sûre est que si vous n'utilisez pas de requêtes paramétrées (et que vous n'êtes pas, exclusivement, ici, car vous concatéez la chaîne d'entrée dans votre SQL), alors vous 'n'est pas sûr.


8 commentaires

Cela ne répond pas à la question. C'est pourquoi n'est-ce pas en sécurité? Pouvez-vous démontrer cela?


OK, alors quel texte pourrait-ils entrer cela affecterait le serveur?


Voir Stackoverflow.com/questions/139199/... pour les cas théoriques. Je n'ai pas dit que vous n'étiez pas protégé, je viens de dire que la seule hypothèse Safe est que vous n'êtes sécurisé que si vous utilisez des requêtes paramétrisées pour toutes les données provenant des utilisateurs.


@Mark, merci pour le lien. Je savais que je n'étais pas la première personne à demander, mais je n'ai pas pu trouver le poste pertinent.


@Mark - Bon lien. La troncature tampon ne s'applique pas ici cependant. Le truc du backslash MySQL ne s'applique pas. L'unicode est très intéressant. J'ai testé sur SQL Server et il est en effet vrai qu'il convertira le `'`` U + 02BC personnage à une apostrophe régulière. Cela repose sur une fonte au chargeur / Varchar (par opposition à Unicode) se produisant à un moment donné, ce qui ne se produira pas lors de l'exécution d'une requête régulière.


Martin, dis-tu si je colle votre caractère dans ma zone de texte, le code VB ne le reconnaîtra pas comme une citation unique, mais le serveur va? C'est exactement le genre de réponse que je recherche. Je veux tester s'ils collectent accidentellement quelque chose, même s'ils sont mécontents et la chasse à des moyens de casser / tester le serveur. Je vais le tester mon.


@Beth - Oui, il serait converti en une apostrophe régulière, mais uniquement si vous lancez la saisie de l'utilisateur sur char à un moment donné. Si cela est maintenu à Unicode, cette question ne surgira pas.


Merci, @martin Smith. Je ne fais rien d'autre, je ne fais que passer le SQL à travers, alors je pense que je devrais avoir tout couvert, comme certains d'autres l'ont dit.



2
votes

Peu importe la manière dont vous nettoyez l'entrée de l'utilisateur augmenter la surface d'attaque est le problème réel avec ce que vous faites. Si vous regardez en arrière de l'histoire de l'injection SQL, vous remarquerez que de nouvelles méthodes neuves et encore plus créatives de faire des ravages via elles ont émergé au fil du temps. Bien que vous ayez peut-être évité le connu, il est toujours ce qui se cache juste autour du coin qui rend ce type de code difficile à la production. Vous feriez mieux d'utiliser simplement une approche différente.


2 commentaires

Je comprends pour une application Web où les mises à jour sont ouvertes au monde, cela a du sens, mais la principale chose que mes utilisateurs souhaitent avoir l'application personnalisée dont ils ont besoin pour afficher et modifier leurs données, que Dynamic SQL me permet de faire sans changer de code quand leur schéma DB change.


Je comprend. Un autre problème avec Dynamic SQL est l'injection de caractères entraînant des effets secondaires. Les requêtes paramétrées ou tirer parti de LINQ vers SQL / Entity Framework permettent simplement à votre accès des données échoué.



1
votes

Vous ne voulez jamais jamais construire une instruction SQL à l'aide d'une entrée utilisateur qui sera ensuite exécutée directement. Cela conduit à des attaques d'injection SQL, comme vous l'avez trouvé. Il serait trivial que quelqu'un dépose une table dans votre base de données, comme vous l'avez décrit.

Vous souhaitez utiliser des requêtes paramétrées, où vous construisez une chaîne SQL à l'aide d'espaces réservés pour les valeurs, puis transmettez les valeurs dans ces paramètres. .

Utiliser VB que vous feriez quelque chose comme: xxx

(Exemple pris de ICI ) (Pas non plus, je ne suis pas un programmeur VB, cela pourrait donc ne pas être une syntaxe appropriée, mais cela obtient le point)


6 commentaires

@Canspice - Je ne pense pas que vous lisiez la question correctement. Ce n'est pas trivial car en échappant à la citation unique, ce qui est envoyé doit être traité comme des données.


En fait, j'essaie de trouver l'attaque. Le SQL dans la question ne cause pas une. Pouvez-vous produire SQL qui fait?


Comme je l'ai dit, je ne suis pas un programmeur VB. Qu'est-ce que _formattype = displayset.formattypes.text faire? Est-ce que cela ne définit que ageelimiter si l'entrée est du texte? Je suppose que ce que je demande, c'est "Comment aiséLimiter est-il défini sur false?"


S'ils s'attendaient à entrer une valeur numérique, l'aisélimiteur est faux. Mon objet DisplaySet contient un formatTypes Enum avec trois valeurs, numérique, texte et mémo, qui déterminent comment formater l'instruction de mise à jour. Un type de mémo est stocké sous forme de type de texte sur le serveur SQL, pas Varcharchar (), la syntaxe est donc différente. Les valeurs numériques n'ont pas besoin du délimiteur environnant.


D'accord, donc s'ils s'ils sont censés entrer une valeur numérique, la chaîne "0; la table de dépose ordinatrice--" Vous venez de vous avoir en difficulté car votre instruction SQL est maintenant Mettre à jour le fichier de jeu de CaseField = 0; Table de goutte ordettable - .


@Canspice Vous supposez que je ne valide pas les entrées numériques que je fais. Non seulement il doit être numérique, mais également dans la plage, le BIZ nécessite. Ce n'est pas une application Web, je peux donc ignorer les frappes de frappe non valides.



2
votes

Vous pouvez également évaluer une solution alternative. Génération dynamique de SQL avec des paramètres. Quelque chose comme ceci: xxx


2 commentaires

Je connais la valeur PK car ils ont sélectionné la ligne et la colonne à éditer, ce n'est donc que la valeur qu'ils souhaitent mettre à jour, passée directement sur le serveur.


La raison pour laquelle je ne fais pas est parce que je veux une approche générique pour les mises à jour à travers le contenu des affaires. Je peux utiliser ce même code pour toute mise à jour sur n'importe quel champ de n'importe quel projet. L'introduction des éléments statiques signifie la modification / la compilation / test / le déploiement de code mis à jour, que je souhaite éviter si tout ce qu'ils font est de modifier leur schéma de contenu ou leurs règles de validation.