C# 只能参数化where子句吗?
为了防止sql注入,我尝试使用参数化查询。但我不清楚是否应该只参数化where子句或查询的其他部分。例如,我正在尝试改进以下查询:C# 只能参数化where子句吗?,c#,sql,sql-server,C#,Sql,Sql Server,为了防止sql注入,我尝试使用参数化查询。但我不清楚是否应该只参数化where子句或查询的其他部分。例如,我正在尝试改进以下查询: string strQ = @";WITH lstTable as ( SELECT ROW_NUMBER() OVER(ORDER BY " + sort + @") AS RowNum, * FROM ( SELECT * FROM S
string strQ = @";WITH lstTable as (
SELECT ROW_NUMBER() OVER(ORDER BY " + sort + @") AS RowNum, *
FROM (
SELECT *
FROM SystemMessage
WHERE Deleted = 0 ";`
此查询正在网格中使用,根据用户的选择,它将按列名排序。在这种情况下,我需要参数化“排序”吗?您可以正确地说,您不能将参数直接用于此用例。但是,是否需要使用参数取决于
sort
的填充方式
如果它是一个硬编码的列名列表,并且用户只选择列表中要选择的索引,则无需担心参数化,用户在查询中没有直接输入,因此无法向其中插入代码
如果用户直接提供列名,则在传入之前必须清理用户输入,一种方法是使用sql函数清理输入
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]
”的列,并将失败。您可以正确地说,您不能将参数直接用于此用例。但是,是否需要使用参数取决于sort
的填充方式
如果它是一个硬编码的列名列表,并且用户只选择列表中要选择的索引,则无需担心参数化,用户在查询中没有直接输入,因此无法向其中插入代码
如果用户直接提供列名,则在传入之前必须清理用户输入,一种方法是使用sql函数清理输入
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]
”的列,并将失败。您不能参数化标识符,但可以在order by子句中使用基于参数值的大小写表达式。或者我不了解该问题,或者您不了解该问题。参数化查询(据我所知)不会阻止sql注入。在发出SQL请求之前清理数据将对您帮助更大。如果您的排序值不是由用户输入的,而是从列表中选择的,则您没有SQL注入问题-否则,可以。@fiprojects参数化查询肯定会阻止SQL注入。@fiprojects可以提供示例SQL查询来演示您的语句(假设SQL查询中没有用户输入,只允许参数)?您不能参数化标识符,但可以在基于参数值的order by子句中使用大小写表达式。要么我不了解问题,要么您不了解问题。参数化查询(据我所知)不会阻止sql注入。在发出SQL请求之前清理数据将对您帮助更大。如果您的排序值不是由用户输入的,而是从列表中选择的,则您没有SQL注入问题-否则,可以。@fiprojects参数化查询肯定会阻止SQL注入。@fiprojects可以提供示例SQL查询来演示您的语句(假设SQL查询中没有用户输入,只允许参数)?如果传递的字符串是select 1];删除表tablename--
?qouatname将如何防止这种情况发生?@ZoharPeled它将变成[select 1];drop table Name--]
Sql将]]
放在[]
中设置为]
作为文本进行解释。类似于在C语言中执行“\\”
,只得到一个\
。在MSDN文档中,他们展示了一个例子。很高兴知道!我不知道QUOTENAME
实际上会转义字符串中的字符;删除表tablename--
?qouatname将如何防止这种情况发生?@ZoharPeled它将变成[select 1];drop table Name--]
Sql将]]
放在[]
中设置为]
作为文本进行解释。类似于在C语言中执行“\\”
,只得到一个\
。在MSDN文档中,他们展示了一个例子。很高兴知道!我不知道QUOTENAME
实际上会转义字符串中的字符。