2015-11-21 3 views
2

Только что начал новую работу, и я нашел безумно сложный вызов sp_executesql (SQL Server 2008 R2). Я не могу решить, уязвим ли он для SQL-инъекции или нет.Комплекс sp_executesql - уязвим для инъекций?

определяется как единый C# string (так нет доп Спасаясь) следующее:

declare @temp table(keyid int IDENTITY(1,1) PRIMARY KEY, name nvarchar(50)); 
insert into @temp (name) select distinct name from SOMEWHERE where [email protected]; 

declare @names nvarchar(max); 
declare @dyn nvarchar(max); 

-- dynamically build the columns 
select @names = Stuff ((select '],['+name from @temp order by name for XML PATH('')),1,2,'')+']'; 

-- dynamically build the pivot query 
set @dyn = N'select '+ @names +' from (select name, score from TABLE where code='''[email protected]+''') as p PIVOT 
    (max(score) for name in ('+ @names +')) as pivtab'; 

execute sp_executesql @dyn 

И тогда вся партия выполняется как так

exec sp_executesql @query, N'@code nvarchar(500)',@code=N'..something..' 

Так @code является одновременно используется должным образом (в инструкции вставки), но также плохо использовались при построении @dyn@names тоже, одно из этих полей имен может содержать вредоносный скрипт).

Похоже на плохой запах кода, но я не могу написать значение для @code, которое выполнит произвольный SQL. И мне не хватает полномочий просто заставить проблему.

Кто-нибудь знает, безопасен этот тип или нет? Спасибо

+0

Если динамический поворотный душевнобольно комплекс вы, вероятно, не видят безумно сложные запросы. – lad2025

+0

Но это безопасно? Мое предпочтение заключается не в том, чтобы использовать динамический SQL, как это. Я бы развернул его на прикладном уровне. – Hyjrt6534

+0

@code vunerable для одного – Paparazzi

ответ

2

Это выглядит как классический динамик PIVOT.

declare @temp table(keyid int IDENTITY(1,1) PRIMARY KEY, name nvarchar(50)); 

insert into @temp (name) 
select distinct name from SOMEWHERE where [email protected]; 

declare @names nvarchar(max) 
     ,@dyn nvarchar(max); 

-- dynamically build the columns 
select @names = Stuff ((select ','+ QUOTENAME(name) 
         from @temp 
         order by name 
         for XML PATH('')),1,1,''); 

-- dynamically build the pivot query 
set @dyn = 
    N'select '+ @names +' from (select name, score from TABLE where [email protected]) 
    as p PIVOT 
    (max(score) for name in ('+ @names +')) as pivtab'; 

execute dbo.sp_executesql 
     @dyn, 
     N'@code DATATYPE', 
     @code; 

Я:

  1. Использование QUOTENAME вместо конкатенации ],[ (так же, как хорошая практика)
  2. параметризующих @code (возможно вектор атаки, пользователь может передать вредоносный код)

Если вы можете сделать PIVOT в прикладном уровне, сделайте это.

Я recommed также читать The Curse and Blessings of Dynamic SQL

+0

Спасибо, это очень полезно - я не думал о том, чтобы указать @code в качестве параметра внутреннего запроса. – Hyjrt6534

+0

@ jane0027 Выполняя это, вы уверены, что код как 'blabla '; DROP TABLE ...; - 'параметризуется. – lad2025

+0

+1. , , Стоит отметить, что с предложенными изменениями код не должен быть уязвимым, потому что имена поступают из системных таблиц и правильно цитируются. Исходный код был бы уязвим для прикрепления, где '@code начинался с одной цитаты. –