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 声明它是自己的,基本上可以在你的数据库上执行他想要的任何东西。
我想创建一个 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 声明它是自己的,基本上可以在你的数据库上执行他想要的任何东西。