Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

SQL SERVER – Um truque de manipulação de SQL dinâmico para evitar ataques de injeção de SQL?

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.