4

目前,我正在通过执行类似的操作来创建 SQL 查询

string SQLQuery = "SELECT * FROM table WHERE ";
foreach(word in allTheseWords)
{
     SQLQuery = SQLQuery + " column1 = '" + word + "' AND";
}

我知道这可能会导致 SQL 注入攻击。我不知道如何将数组作为参数传递

where report in @allTheseWords

===========

我正在使用 SQL Server 2012

4

6 回答 6

3

不幸的是,如果不为表值参数添加用户定义的类型,就无法将数组作为参数传递。绕过此限制的最简单方法是在循环中为数组的每个元素创建单独命名的参数,然后将值绑定到这些元素中的每一个:

string SQLQuery = "SELECT * FROM table WHERE column1 in (";
for(int i = 0 ; i != words.Count ; i++) {
    if (i != 0) SQLQuery += ",";
    SQLQuery += "@word"+i;
}
...
for(int i = 0 ; i != words.Count ; i++) {
    command.Parameters.Add("@word"+i, DbType.String).Value = words[i];
}

您还可以创建一个临时表,在其中插入单个单词,然后执行与临时单词表进行内连接的查询。

于 2013-01-28T15:35:12.710 回答
2

使用 ADO,您可以在 params 的帮助下完成

SqlConnection Con = new SqlConnection(conString);
SqlCommand Com = new SqlCommand();
string SQLQuery = "SELECT * FROM table WHERE ";
int i=1;
foreach(word in words)
{
      Com.Parameters.Add("@word"+i.ToString(),SqlDbType.Text).Value = word;
      SQLQuery = SQLQuery + " column1 = '@word"+i.ToString()+"' AND ";
      i++;
}
Com.CommandText =SQLQuery;
于 2013-01-28T15:43:12.633 回答
2

以下是微软的建议:

  1. 使用代码分析来检测 Visual Studio 项目中容易出现 sql 注入的区域;
  2. 请参阅有关如何降低攻击风险的文章:

简而言之,他们谈论:

  • 使用存储过程。
  • 使用参数化的命令字符串。
  • 在构建命令字符串之前验证用户输入的类型和内容。

顺便说一句,您可以在构建过程中启用静态分析并对其进行配置,以便当安全规则被破坏时,构建也会中断。确保您的团队编写安全代码的好方法!

于 2013-01-28T17:26:04.887 回答
1

对于 SQL Server,您将使用Table-Valued Parameter。SQL 有一个结构,它表示同一类型的多个项目的集合。它被称为表。它没有数组。


当然,您应该更新的查询:

where report in @allTheseWords

不等同于您的原始查询,但可能更接近意图。在使用构造的查询中AND,您是说同一行中的同一列必须等于多个不同的单词。除非所有单词都相等,否则这将永远不会返回任何行。更新后的查询回答是否有任何单词匹配,而不是all

于 2013-01-28T15:36:18.597 回答
1

您需要使用准备好的语句。处理这些的方式是您编写查询并为要使用的值放置占位符。这是一个例子:

SELECT * FROM table WHERE column1 = @word

然后,您必须经历一个准备阶段,SQL 引擎知道它需要将参数绑定到查询。然后,您可以执行查询。SQL 引擎应该知道何时以及如何解释您绑定到查询的参数。

这里有一些代码可以做到这一点:

SqlCommand command = new SqlCommand(null, rConn);

// Create and prepare an SQL statement.
command.CommandText = "SELECT * FROM table WHERE column1 = @word";
command.Parameters.Add ("@word", word);
command.Prepare();
command.ExecuteNonQuery();
于 2013-01-28T15:36:27.407 回答
0
I combine the use of params with HtmlEncoding(to get rid of special characters where not needed). Give that a shot.

using (SqlConnection conn = new SqlConnection(conString))
{     
    string sql = "SELECT * FROM table WHERE id = @id";
    using (SqlCommand cmd = new SqlCommand(sql, conn))
    {
        cmd.paramaters.AddWithValue("@id", System.Net.WebUtility.HtmlEncode(id));
        conn.Open();
        using (SqlDataReader rdr = cmd.ExecuteReader())
        {

        }
    }
}
于 2013-01-28T18:26:30.813 回答