Permitindo que um usuário passe o nome da tabela e o nome da coluna, evitando a injeção de SQL

Eu tenho uma página da Web (intranet) (ASP.NET C #) que permite aos usuários criar uma tabela em um database específico no SQL-Server, nome da tabela e nome da coluna são campos de texto livre e a estrutura real é determinada por alguns dropdowns. Estou ciente de que passar a instrução create table como string pura concatenada com o texto das minhas checkboxs de texto é suscetível à injeção de SQL. Dado que eu estou passando os nomes reais dos objects db que ainda não existem, em vez de parâmetros, existe alguma maneira de evitar a possibilidade de injeção diferente de verificar cada checkbox de texto para caracteres ilegais antes de concatenar a seqüência de caracteres?

Isto é o que QUOTENAME() foi criado para resolver. Você passa seus nomes de coluna e tabela como parâmetros para QUOTENAME() e, em seguida, usa a saída dele para representar objecs em seu database 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 solta minha outra tabela.

insira a descrição da imagem aqui