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

Permitir que um usuário passe o nome da tabela e o nome da coluna enquanto impede a injeção de SQL


Isto é o que QUOTENAME() foi criado para resolver. Você passa seus nomes de coluna e tabela como parâmetros para QUOTENAME() e então você usa a saída dele para representar objetos em seu banco de dados em uma consulta sql dinâmica.
//The evil name tries to expliot code like:
//  set @sql = N'CREATE TABLE [' + @tablename + N'] (Foo int)'
var evilName = "someName] (Foo int); Drop table students --";

var query = @"
declare @sql as nvarchar(max)
set @sql = N'CREATE TABLE ' + QUOTENAME(@tablename) + N' (Foo int)'
exec sp_executesql @sql
";
using(var connection = new SqlConnection(ConnectionString))
using(var command = new SqlCommand(query, connection))
{
    command.Parameters.Add("@tablename", SqlDbType.NVarChar, 128).Value = evilName ;
    connection.Open();
    command.ExecuteNonQuery();
}

A consulta que será executada no servidor será
CREATE TABLE [someName]] (Foo int); Drop table students --] (Foo int)

que cria uma tabela com um nome de tabela válido e não descarta minha outra tabela.