J'ai effectué la procédure stockée suivante:
ALTER PROCEDURE usp_actorBirthdays (@nameString nvarchar(100), @actorgender nvarchar(100))
AS
SELECT ActorDOB, ActorName FROM tblActor
WHERE ActorName LIKE '%' + @nameString + '%'
AND ActorGender = @actorgender
Maintenant, j'ai essayé de faire quelque chose comme ça. Je me trompe peut-être, mais je veux être sûr qu'une telle procédure peut empêcher toute injection SQL:
EXEC usp_actorBirthdays 'Tom', 'Male; DROP TABLE tblActor'
L'image ci-dessous montre le SQL ci-dessus en cours d'exécution dans SSMS et les résultats affichés correctement au lieu d'une erreur:
Btw, j'ai ajouté cette partie après le point-virgule après l'exécution de la requête. Ensuite, je l'ai exécuté à nouveau, mais quand j'ai vérifié pour voir si la table tblActor existe ou non, elle était toujours là. Est-ce que je fais quelque chose de mal? Ou est-ce vraiment anti-injection? Je suppose que ce que j'essaie de demander ici aussi, c'est qu'il s'agit d'une procédure stockée comme celle-ci? Je vous remercie.
EXEC usp_actorBirthdays 'Tom', 'Male''; DROP TABLE tblActor'
Réponses:
Ce code fonctionne correctement car il est:
Pour que l'injection SQL fonctionne, vous devez créer une chaîne de requête (ce que vous ne faites pas) et ne pas traduire les apostrophes simples (
'
) en apostrophes d'échappement (''
) (ceux-ci sont échappés via les paramètres d'entrée).Dans votre tentative de passer une valeur "compromise", la
'Male; DROP TABLE tblActor'
chaîne est juste cela, une chaîne ordinaire.Maintenant, si vous faisiez quelque chose comme:
alors cela serait sensible à l'injection SQL car cette requête n'est pas dans le contexte pré-analysé actuel; cette requête n'est qu'une autre chaîne pour le moment. Ainsi, la valeur de
@InputParam
pourrait être'2015-10-31'; SELECT * FROM PlainTextCreditCardInfo;
et cela pourrait poser un problème car cette requête serait rendue et exécutée comme suit:C'est l'une (parmi plusieurs) raisons principales d'utiliser les procédures stockées: intrinsèquement plus sécurisées (enfin, tant que vous ne contournez pas cette sécurité en créant des requêtes comme je l'ai montré ci-dessus sans valider les valeurs des paramètres utilisés). Bien que si vous avez besoin de construire Dynamic SQL, la méthode préférée est de le paramétrer également en utilisant
sp_executesql
:En utilisant cette approche, une personne tentant de transmettre
'2015-10-31'; SELECT * FROM PlainTextCreditCardInfo;
unDATETIME
paramètre d'entrée obtiendrait une erreur lors de l'exécution de la procédure stockée. Ou même si la procédure stockée acceptait@InputParameter
commeNVARCHAR(100)
, elle devrait être convertieDATETIME
en a pour passer à cetsp_executesql
appel. Et même si le paramètre dans Dynamic SQL est un type chaîne, entrant dans la procédure stockée en premier lieu, toute apostrophe unique serait automatiquement échappée vers une apostrophe double.Il existe un type d'attaque moins connu dans lequel l'attaquant essaie de remplir le champ d'entrée avec des apostrophes de sorte qu'une chaîne à l'intérieur de la procédure stockée qui serait utilisée pour construire le SQL dynamique mais qui est déclarée trop petite ne peut pas tout contenir et repousse l'apostrophe de fin et se retrouve en quelque sorte avec le nombre correct d'apostrophes afin de ne plus être "échappé" dans la chaîne. Cela s'appelle SQL Truncation et a été évoqué dans un article du magazine MSDN intitulé "Nouvelles attaques de troncature SQL et comment les éviter", par Bala Neerumalla, mais l'article n'est plus en ligne. Le problème contenant cet article - l' édition de novembre 2006 de MSDN Magazine - est uniquement disponible en tant que fichier d'aide Windows (en .chmformat). Si vous le téléchargez, il peut ne pas s'ouvrir en raison des paramètres de sécurité par défaut. Si cela se produit, faites un clic droit sur le fichier MSDNMagazineNovember2006en-us.chm et sélectionnez "Propriétés". Dans l'un de ces onglets, il y aura une option pour "Faire confiance à ce type de fichier" (ou quelque chose comme ça) qui doit être vérifiée / activée. Cliquez sur le bouton "OK", puis essayez à nouveau d'ouvrir le fichier .chm .
Une autre variante de l'attaque de troncature est, en supposant qu'une variable locale est utilisée pour stocker la valeur "sûre" fournie par l'utilisateur car elle a doublé les guillemets simples afin d'être échappée, de remplir cette variable locale et de placer la guillemet simple à la fin. L'idée ici est que si la variable locale n'est pas correctement dimensionnée, il n'y aura pas assez de place à la fin pour le deuxième guillemet simple, laissez la variable se terminant par un guillemet simple qui se combine ensuite avec le guillemet simple qui termine la valeur littérale dans le SQL dynamique, transformant ce guillemet simple de fin en un guillemet simple d'échappement incorporé, et le littéral de chaîne dans le SQL dynamique se termine ensuite par le guillemet simple suivant qui était destiné à commencer le littéral de chaîne suivant. Par exemple:
Ici, le Dynamic SQL à exécuter est maintenant:
Ce même Dynamic SQL, dans un format plus lisible, est:
Il est facile de résoudre ce problème. Effectuez simplement l'une des opérations suivantes:
N'utilisez pas de variable locale pour stocker la valeur "fixe"; il suffit de mettre
REPLACE()
directement dans la création du Dynamic SQL:Le Dynamic SQL n'est plus compromis:
Remarques sur l'exemple Trunction ci-dessus:
DELETE tableName
être destructeur, mais moins susceptible d'ajouter un utilisateur détourné ou de changer un mot de passe administrateur.Pour des informations plus détaillées sur l'injection SQL (couvrant divers SGBDR et scénarios), veuillez consulter les éléments suivants du projet de sécurité des applications Web ouvertes (OWASP):
Test de l'injection SQL
Réponse de dépassement de pile associée à l'injection SQL et à la troncature SQL:
Dans quelle mesure T-SQL est-il sûr après avoir remplacé le caractère d'échappement?
la source
La simple question est que vous ne confondez pas du tout les données avec la commande. Les valeurs des paramètres ne sont jamais traitées comme faisant partie de la commande et ne sont donc jamais exécutées.
J'ai blogué à ce sujet sur: http://blogs.lobsterpot.com.au/2015/02/10/sql-injection-the-golden-rule/
la source