创建安全的 SQL 语句作为字符串

问题描述 投票:0回答:5

我正在使用 C# 和 .NET 3.5。我需要生成并存储一些 T-SQL 插入语句,这些语句稍后将在远程服务器上执行。

例如,我有一组员工:

new Employee[]
{
   new Employee { ID = 5, Name = "Frank Grimes" },
   new Employee { ID = 6, Name = "Tim O'Reilly" }
}

我需要得到一个字符串数组,如下所示:

"INSERT INTO Employees (id, name) VALUES (5, 'Frank Grimes')",
"INSERT INTO Employees (id, name) VALUES (6, 'Tim O''Reilly')"

我正在查看一些使用 String.Format 创建插入语句的代码,但这感觉不对。我考虑过使用 SqlCommand(希望做类似这样的事情),但它没有提供将命令文本与参数结合起来的方法。

仅替换单引号并构建字符串就足够了吗?

string.Format("INSERT INTO Employees (id, name) VALUES ({0}, '{1}')",
    employee.ID,
    replaceQuotes(employee.Name)
    );

这样做时我应该注意什么?源数据相当安全,但我不想做太多假设。

编辑:只是想指出,在这种情况下,我没有 SqlConnection 或任何直接连接到 SQL Server 的方法。这个特定的应用程序需要生成 sql 语句并将它们排队以便在其他地方执行 - 否则我将使用 SqlCommand.Parameters.AddWithValue()

c# .net sql concatenation stringbuilder
5个回答
19
投票

像这样创建 SqlCommand 对象:

SqlCommand cmd = new SqlCommand(
        "INSERT INTO Employees (id, name) VALUES (@id, @name)", conn);

SqlParameter param  = new SqlParameter();
param.ParameterName = "@id";
param.Value         = employee.ID;

cmd.Parameters.Add(param);

param  = new SqlParameter();
param.ParameterName = "@name";
param.Value         = employee.Name;

cmd.Parameters.Add(param);

cmd.ExecuteNonQuery();

8
投票

使用参数化命令。还将参数传递到远程服务器,并调用 SQL Server,仍然保持 SQL 本身和参数值之间的区别。

只要你不把数据当成代码,就应该没问题。


5
投票

以这种方式修复替换引号功能:

string replaceQuotes(string value) {
     string tmp = value;
     tmp = tmp.Replace("'", "''");
     return tmp;
}

干杯!


1
投票

嗯,我同意其他人的观点,您应该使用参数化查询,并且就此保留。但是如何将这些 sql 语句传递到远程服务器呢?您是否有某种类型的服务(例如 Web 服务)可以接受并执行任意 Sql 命令,或者您的客户端应用程序是否会直接访问数据库?

如果您通过某种代理,那么无论您在客户端上如何清理数据,黑客都可以绕过您的应用程序并攻击该服务。在这种情况下,请按照 Cade 的建议进行操作,并将数据作为 XML 或您选择的任何格式(JSON、二进制等)传递。然后在实际运行命令之前构建 SQL。


0
投票

为了避免注入,您需要将数据发送到远程服务器(可能以 XML 形式),然后在远程服务器上,数据应转换回适当的数据类型并在参数化查询或存储过程中使用。

© www.soinside.com 2019 - 2024. All rights reserved.