C# 避免函数中的 SQL 注入

C# avoid SQL Injection in a function

我想创建一个 class 来帮助 SELECT、INSERT、UPDATE 和 DELETE SQL 服务器数据库,但我通过搜索发现有 "sql injection" 避免它的方法是使用如下函数:

private static void Select() {
    string cmdStr = "SELECT FirstName, LastName, Telephone FROM Person WHERE FirstName = @FirstName";
    using (SqlConnection connection = new SqlConnection(ConnectionString))
    using (SqlCommand command = new SqlCommand(cmdStr, connection)) {
        command.Parameters.AddWithValue("@FirstName", "John");
        connection.Open();
        SqlDataReader reader = command.ExecuteReader();
        while (reader.Read()) {
            string output = "First Name: {0} \t Last Name: {1} \t Phone: {2}";
            Console.WriteLine(output, reader["FirstName"], reader["LastName"], reader["Telephone"]);
        }
    }
}

下面的函数可以有sql注入吗?

  private static void SelectWithWhere(String query, String[] parameters)
        {

            {
                string cmdStr = "SELECT FirstName, LastName, Telephone FROM Person WHERE "+parameters[0];
                using (SqlConnection connection = new SqlConnection(ConnectionString))
                using (SqlCommand command = new SqlCommand(cmdStr, connection))
                {
                    command.Parameters.AddWithValue("@FirstName", parameters[0]);
                    connection.Open();
                    SqlDataReader reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        string output = "First Name: {0} \t Last Name: {1} \t Phone: {2}";
                        Console.WriteLine(output, reader["FirstName"], reader["LastName"], reader["Telephone"]);
                    }
                }
            }
        }

上面的函数没有,因为你将值作为 SqlArgument 传递。而不是作为 SQL 的一部分。第二种方法,是的,如果参数包含这样的东西:

parameters = new [] { "1<>1;DROP TABLE PERSON;" }

您要执行的查询最终会是:

"SELECT FirstName, LastName, Telephone FROM Person WHERE 1<>1;DROP TABLE PERSON;"

哪个 SQL 服务器将执行第一条语句 (SELECT),然后执行第二条语句 DROP

只要您使用 SqlParameter 将用户输入添加到查询中,您就不会受到 Sql 注入。

如果您使用字符串连接,则需要解析用户输入以确保您没有发出恶意查询。

老实说,超出了这个问题的范围,如今直接编写 Ado.Net 代码已经很不合时宜了。有大量的 micro-Orms 可以让您的生活变得轻松。

每次您使用用户提供的输入生成 SQL 语句时,您就打开了 SQL 注入的大门。 避免sql注入的方法是使用参数。

第一个函数是安全的,但如果您不控制所提供的 String[] parameters,第二个函数可能容易受到 sql 注入攻击。如果用户为这个数组提供值(直接或间接),他可以传递一个 sql 声明它是自己的,基本上可以在你的数据库上执行他想要的任何东西。