Devrions-nous toujours utiliser QUOTENAME pour se protéger des attaques par injection?


9

Je regardais une ancienne procédure stockée aujourd'hui et j'ai remarqué qu'elle utilisait quotenameles paramètres d'entrée. Après avoir creusé pour comprendre ce que cela fait exactement, je suis tombé sur ce site . Je comprends maintenant ce qu'il fait et comment l'utiliser, mais le site dit qu'il est utilisé comme atténuation des attaques par injection SQL. Lorsque je développais des applications qui interrogeaient directement une base de données, en utilisant asp.net, j'utilisais les paramètres ADO.Net pour transmettre l'entrée utilisateur en tant que valeur littérale et je ne me souciais jamais vraiment de la protéger dans mes procédures stockées.

J'écris maintenant une procédure stockée qui sera utilisée par des applications que je n'écris pas, je dois donc essayer de me protéger contre les attaques par injection au niveau de la procédure, est quotenamela meilleure façon de le faire ou existe-t-il une fonction plus récente / meilleure méthode?

Code qui m'a amené sur ce modèle de pensée ( @parm1est un paramètre d'entrée utilisateur):

'SELECT project [Project], project_desc [Description], 
        customer [Customer], cpnyid [Company]
FROM PJPROJ (nolock)
where project like ' + quotename(@parm1,'''') + '

Réponses:


17

Oui, les choses n'ont pas beaucoup changé dans ce domaine, vous devez utiliser quotenamepour tous les noms d'objets de serveur SQL qui sont utilisés dans SQL dynamique (surtout s'ils sont fournis en externe à votre code). En plus de l'atténuation des injections SQL, cela signifie également que votre code fonctionnera correctement pour les noms d'identificateurs non standard.

La fonction n'est cependant appropriée que pour les noms d'objets (par exemple, noms de table, de colonne, de base de données).

Vous devriez essayer de paramétrer tout le reste et utiliser sp_executesql, en passant des paramètres plutôt que de les concaténer dans la chaîne de requête.

L'article définitif sur ce sujet est toujours La malédiction et les bénédictions de Dynamic SQL


Éditer. Maintenant que vous avez fourni le code, je vois qu'il passe le deuxième paramètre de 'pour ajouter les guillemets externes et échapper aux guillemets simples en les doublant avant de les injecter dans la chaîne. Ce n'est pas une bonne utilisation de quotename. Il échouera (retournera null) si la chaîne est supérieure à 128 caractères.

De plus, il peut toujours laisser des possibilités d'injection SQL si la chaîne contient U + 02BC au lieu de l'apostrophe standard, puis la chaîne est affectée à un varchar après l'assainissement ( où elle peut être silencieusement convertie en apostrophe régulière )

La bonne façon de procéder consiste à laisser la requête paramétrée. Et puis passez la @parm1valeur àsys.sp_executesql

DECLARE @Sql NVARCHAR(MAX);

SET @Sql = '
SELECT project      [Project],
       project_desc [Description],
       customer     [Customer],
       cpnyid       [Company]
FROM   PJPROJ (nolock)
WHERE  project LIKE @parm1 
';

EXEC sys.sp_executesql
  @Sql,
  N'@parm1 varchar(100)',
  @parm1 = 'foobar%'; 
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.