Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL Injections com substituir aspas simples e validar inteiros


Se este é um projeto legado que é codificado dessa maneira, embora não seja o ideal, atualmente não estou ciente de nenhuma maneira de ser suscetível à injeção de SQL, desde que cada string seja tratada dessa maneira e as consultas sejam apenas simples como você mostrou.

No entanto, não posso afirmar mais certeza do que isso. Sem usar consultas parametrizadas sempre existe a possibilidade de existir alguma vulnerabilidade que você ainda não considerou.

O escape manual das cotações é propenso a erros e, às vezes, pode falhar de maneiras difíceis de prever com antecedência. Por exemplo com a seguinte tabela
CREATE TABLE myTable(title VARCHAR(100))
INSERT INTO myTable VALUES('Foo')

E procedimento armazenado usando SQL dinâmico construído com concatenação de strings
CREATE PROC UpdateMyTable
@newtitle NVARCHAR(100)
AS
/*
Double up any single quotes
*/
SET @newtitle = REPLACE(@newtitle, '''','''''')

DECLARE @UpdateStatement VARCHAR(MAX)

SET @UpdateStatement = 'UPDATE myTable SET title='''  + @newtitle + ''''

EXEC(@UpdateStatement)

Você pode tentar o seguinte

Atualização normal
EXEC UpdateMyTable N'Foo'
SELECT * FROM myTable /*Returns "Foo"*/

Tentativa de injeção de SQL frustrada
EXEC UpdateMyTable N''';DROP TABLE myTable--'
SELECT * FROM myTable  /*Returns "';DROP TABLE myTable--"*/

A tentativa de injeção de SQL é bem-sucedida e descarta a tabela
EXEC UpdateMyTable N'ʼ;DROP TABLE myTable--'
SELECT * FROM myTable  /*Returns "Invalid object name 'myTable'."*/

O problema aqui é que a terceira consulta passa U+02BC em vez do apóstrofo padrão e, em seguida, a string é atribuída a um varchar(max) depois que o saneamento ocorre, o que silenciosamente converte isso em um apóstrofo regular.

Até eu ler a resposta aqui esse problema nunca teria me ocorrido.