为了防止sql注入,我尝试使用参数化查询。但是,我不清楚我是否应该只对where子句或查询的其他部分进行参数化。例如,我试图改进以下查询:
string strQ = @";WITH lstTable as (
SELECT ROW_NUMBER() OVER(ORDER BY " + sort + @") AS RowNum, *
FROM (
SELECT *
FROM SystemMessage
WHERE Deleted = 0 ";`此查询正在网格中使用,根据用户的选择,它将按列名进行排序。在这种情况下,我需要进行“排序”吗?
发布于 2016-03-16 20:37:48
您是正确的,您不能为这个用例直接使用参数。但是,如果您需要使用参数,则取决于sort是如何填充的。
如果它是一个硬编码的列名列表,并且用户只是选择列表中的哪些索引--您不需要担心参数化,那么用户在查询中没有直接的输入,所以他们不能将代码注入其中。
如果用户直接提供列名,则必须在传入之前清理用户输入,一种方法是使用sql函数QUOTENAME清理输入。
string strQ = @"
declare @query nvarchar(max)
set @query = ';WITH lstTable as (
SELECT ROW_NUMBER() OVER(ORDER BY' + QUOTENAME(@sortColumn) + ') AS RowNum, *
FROM (
SELECT *
FROM SystemMessage
WHERE Deleted = 0 '
exec sp_executesql @query";这样做所做的就是传递给@sortColumn的任何字符串,它将正确地将[ ]包装在该字符串值周围。然后,它在动态生成的字符串中使用该导出值,并使用sp_executesql运行该值。
一个重要的注意事项是,该示例目前只适用于单个列名,您需要在每个列中添加一个QUOTENAME和一个新参数。如果你真的尝试通过FirstName, LastName,它就会变成
;WITH lstTable as (
SELECT ROW_NUMBER() OVER(ORDER BY [FirstName, LastName]) AS RowNum, *
FROM (
SELECT *
FROM SystemMessage
WHERE Deleted = 0当执行时,它将尝试找到一个名为"[FirstName, LastName]“的列,并将失败。
https://stackoverflow.com/questions/36046311
复制相似问题