SQL Server tem muitas coisas para aprender e eu sempre acho isso incrível. Minhas conversas com clientes geralmente trazem questões de segurança, especialmente em torno de SQL Injection. Muitos alegaram que o SQL Injection é um problema do SQL Server. Leva algum tempo para que eu saiba que não há nada sobre SQL Server e SQL Injection. SQL Injection é um resultado de práticas de codificação erradas. Uma das recomendações que dou é sobre não usar SQL dinâmico. Pode haver algumas situações em que você não pode evitá-lo. Meu único conselho seria, evite se possível. Neste blog, eu demonstraria um problema de SQL Injection devido ao SQL dinâmico e uma possível solução que você pode ter.
Vamos supor que temos uma página de pesquisa simples onde o usuário pode usar a pesquisa em branco ou fornecer filtro em qualquer campo. Fornecemos dois campos para usar “Nome” e “Sobrenome”. O usuário digita algo e clica em pesquisar. Aqui está nosso código de procedimento armazenado que é acionado nos bastidores.
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
Se eu usar essa string para executar no sobrenome ”;solte a tabela t1–
EXEC search_first_or_last '%K%', ''';drop table t1--'
A string dinâmica seria
SELECT FirstName, MiddleName, LastName FROM Person. Person WHERE 1 = 1 AND FirstName LIKE '%K%' AND LastName LIKE '';DROP TABLE t1--'
Você vê o problema? Sim, os usuários podem descartar a tabela t1 se o código estiver sendo executado em uma conta de alto privilégio.
Uma das soluções do problema seria usar sp_executesql. Aqui está a melhor versão usando
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
Espero que você possa usar isso e implementar em seu projeto. Você está usando essas técnicas simples em seu código de produção? Você já enfrentou problemas semelhantes durante a auditoria? Deixe-me saber de seus aprendizados.