Eu encontrei algumas exec(sql)
declarações enterradas no código. Eles estão lá por um bom motivo, porque essas instruções não podem ser escritas diretamente, mas são um vetor de ataque óbvio.
Existe uma alternativa segura para exec(some sql)
? Algo que será paremetrizado corretamente, incluindo nomes de tabelas em declarações?
Para certos tipos de parametrização, não vai importar se você usa
EXEC()
ousp_executesql
, porque algumas coisas não podem ser parametrizadas de qualquer maneira. Por exemplo, você expressou nos comentários (atualize sua pergunta para ser mais específico sobre seus requisitos!) que está parametrizando nomes de tabelas, mas eles não podem ser parametrizados porque precisam ser expressos literalmente para SQL Server (não tokenize isso e troque em tempo de execução).Para se proteger de vulnerabilidades de nome de tabela, você pode se proteger facilmente assim:
Agora, prefiro usar
sp_executesql
sempre, em parte porque promove o uso de parâmetros fortemente tipados (evitando problemas de injeção de SQL, bem como problemas de aspas simples), mas também porque, em alguns casos, você passará parâmetros para valores parametrizáveis e não parametrizáveis (sim, eu inventei essas palavras). Mais informações:Agora a única coisa que você tem que se preocupar é se alguém é capaz de criar tabelas e pode criar uma tabela nomeada
sys.objects; DROP TABLE foo; --
- mas se você tem alguém em quem não confia, mas tem a capacidade de criar tabelas em seu banco de dados...Dê uma olhada em usar sp_executeSQL em vez disso. Ele é totalmente parametrizado e, portanto, fornece uma sensação muito maior de segurança para consultas dinâmicas (e o uso junto com EXECUTE AS USER em procedimentos com conjuntos de permissões estritos o torna ainda melhor).