SQL Server a tellement de choses à apprendre et je le trouve toujours incroyable. Mes conversations avec les clients soulèvent souvent des questions de sécurité, en particulier autour de l'injection SQL. Beaucoup ont affirmé que l'injection SQL est un problème de SQL Server. Il me faut un certain temps pour leur faire savoir qu'il n'y a rien sur SQL Server et SQL Injection. L'injection SQL est le résultat de mauvaises pratiques de codage. L'une des recommandations que je donne est de ne pas utiliser Dynamic SQL. Il peut y avoir des situations où vous ne pouvez pas l'éviter. Mon seul conseil serait d'éviter si possible. Dans ce blog, je démontrerais un problème d'injection SQL dû au SQL dynamique et une solution possible que vous pouvez avoir.
Supposons que nous ayons une page de recherche simple où l'utilisateur peut utiliser la recherche vide ou fournir un filtre dans n'importe quel champ. Nous avons prévu deux champs pour utiliser « Prénom » et « Nom de famille ». L'utilisateur tape quelque chose et lance la recherche. Voici notre code de procédure stockée qui se déclenche en coulisse.
USE AdventureWorks2014 GO CREATE PROCEDURE search_first_or_last @firstName NVARCHAR(50) ,@lastName NVARCHAR(50) AS BEGIN DECLARE @sql NVARCHAR(4000) SELECT @sql = ' SELECT FirstName ,MiddleName, LastName' + ' FROM Person.Person WHERE 1 = 1 ' IF @firstName IS NOT NULL SELECT @sql = @sql + ' AND FirstName LIKE ''' + @firstName + '''' IF @lastName IS NOT NULL SELECT @sql = @sql + ' AND LastName LIKE ''' + @lastName + '''' EXEC (@sql) END
Si j'utilise cette chaîne pour exécuter dans le nom de famille ”;supprimer la table t1–
EXEC search_first_or_last '%K%', ''';drop table t1--'
La chaîne dynamique serait
SELECT FirstName, MiddleName, LastName FROM Person. Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'
Voyez-vous le problème ? Oui, les utilisateurs peuvent supprimer la table t1 si le code s'exécute sous un compte à privilèges élevés.
L'une des solutions au problème serait d'utiliser sp_executesql. Voici la meilleure version utilisant
CREATE PROCEDURE search_first_or_last @firstName NVARCHAR(50) ,@lastName NVARCHAR(50) AS BEGIN DECLARE @sql NVARCHAR(4000) SELECT @sql = ' SELECT FirstName , MiddleName, LastName' + ' FROM Person.Person WHERE 1 = 1 ' IF @firstName IS NOT NULL SELECT @sql = @sql + ' AND FirstName LIKE @firstName' IF @lastName IS NOT NULL SELECT @sql = @sql + ' AND LastName LIKE @lastName ' EXEC sp_executesql @sql ,N'@firstName nvarchar(50), @lastName nvarchar(50)' ,@firstName ,@lastName END
J'espère que vous pourrez l'utiliser et l'implémenter dans votre projet. Utilisez-vous ces techniques simples dans votre code de production ? Avez-vous déjà rencontré des problèmes similaires lors d'un audit ? Faites-moi part de vos apprentissages.