刚开始一项新作业,我发现对sp_executesql
(SQL Server 2008 R2)的调用异常复杂。我无法决定它是否容易受到SQL注入的攻击。
以下内容被定义为单个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 code=@code;
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='''+@code+''') 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
(在insert语句中)使用得当,但在构造@dyn
(以及@names
,其中一个名称字段可能包含恶意脚本)时使用不当。
这似乎是一种糟糕的代码气味,但我似乎无法为执行任意SQL的@code
编写值。我没有权力强行提出这个问题。
有人知道这种东西是否安全吗?感谢
这看起来像经典的动态PIVOT
。
declare @temp table(keyid int IDENTITY(1,1) PRIMARY KEY, name nvarchar(50));
insert into @temp (name)
select distinct name from SOMEWHERE where code=@code;
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 code=@code)
as p PIVOT
(max(score) for name in ('+ @names +')) as pivtab';
execute dbo.sp_executesql
@dyn,
N'@code DATATYPE',
@code;
我会:
- 使用
QUOTENAME
而不是串联],[
(这也是一种良好的做法) - 参数化
@code
(可能的攻击向量,用户可以传递恶意代码)
如果你能在应用层做PIVOT
,那就做吧。
我还建议阅读The Curse and Blessings of Dynamic SQL