如何防止SQL注入攻击?

时间:2013-01-28 15:33:40

标签: c# sql sql-injection sql-server-2012

目前,我正在通过执行类似

的操作来创建SQL查询
string SQLQuery = "SELECT * FROM table WHERE ";
foreach(word in allTheseWords)
{
     SQLQuery = SQLQuery + " column1 = '" + word + "' AND";
}

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

where report in @allTheseWords

===========

我正在使用SQL Server 2012

6 个答案:

答案 0 :(得分: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];
}

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

答案 1 :(得分: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;

答案 2 :(得分:2)

Here是Microsoft的建议:

  1. 使用代码分析检测Visual Studio项目中易于sql注入的区域;
  2. 请参阅有关如何降低攻击风险的文章:
  3. 总之,他们谈论:

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

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

答案 3 :(得分:1)

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


当然,您所谓的更新查询:

where report in @allTheseWords

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

答案 4 :(得分: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();

答案 5 :(得分: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())
        {

        }
    }
}