【问题标题】:Can you only parameterize the where clause?只能参数化 where 子句吗?
【发布时间】:2016-03-17 04:43:11
【问题描述】:

为了防止 sql 注入,我尝试使用参数化查询。但我不清楚我是否应该只参数化 where 子句或查询的其他部分。例如,我正在尝试改进以下查询:

string strQ = @";WITH lstTable as (
                SELECT ROW_NUMBER() OVER(ORDER BY " + sort + @") AS RowNum, *
                FROM (
                SELECT *
                FROM SystemMessage
                WHERE Deleted = 0  ";`

此查询在网格中使用,根据用户的选择,它将按列名排序。在这种情况下我需要参数化“排序”吗?

【问题讨论】:

  • 您不能参数化标识符,但您可以在 order by 子句中使用基于参数值的 case 表达式。
  • 要么我对问题缺乏了解,要么您对问题缺乏了解。参数化查询不会(据我所知)阻止您进行 sql 注入。在发出 SQL 请求之前对数据进行清理将对您有更多帮助。
  • 如果您的 sort 值不是由用户输入,而是从列表中选择的,那么您没有 SQL 注入问题 - 否则,您会遇到。
  • @fiprojects 参数化查询肯定会阻止 SQL 注入。
  • @fiprojects 您能否提供示例 SQL 查询来演示您的语句(假设 SQL 查询中没有用户输入并且只允许使用参数)?

标签: c# sql sql-server


【解决方案1】:

您是正确的,您不能直接在此用例中使用参数。但是,是否需要使用参数取决于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 的任何字符串,它将正确地将[ ] 包裹在该字符串值周围。然后它在动态生成的字符串中使用该 excaped 值并使用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]”的列并且会失败。

【讨论】:

  • 如果传递的字符串是select 1];drop table tablename --怎么办? qouatname 将如何保护它?
  • @ZoharPeled 它将变为[select 1]];drop table tablename --] Sql 将[ ] 中的]] 设置为],并作为文本插入。类似于在 C# 中执行 "\\" 以获得 \ 的方式。在 MSDN 文档中,他们展示了一个示例。
  • 很高兴知道!我不知道QUOTENAME 实际上转义了字符串中的字符。
猜你喜欢
  • 2016-03-30
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-26
相关资源
最近更新 更多