SQL参数化与使用string.format

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

在防范SQL注入方面,对于更简单的查询,以下策略之一是否比其他策略更有效?:

  1. 使用参数化: using (SqlCommand command = new SqlCommand(@"SELECT * FROM @table", connection)) { command.Parameters.AddWithValue("@table", table_name); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { ... } } }
  2. 使用string.Formatusing (SqlCommand command = new SqlCommand(string.Format(@"SELECT * FROM {0}",table_name), connection)) using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { ... } }
c# sql-server sql-injection sql-parametrized-query
3个回答
1
投票

参数化在SQL注入方面更安全。处理字符串和日期也更好。例如,如果您的字符串是这样的:

"I haven't sleep in two days"

如果您在查询中尝试String.Format它,您将不得不加倍'字符,否则您的查询将失败。好像你参数化它,SQL将自己做。 我做String.Format的唯一原因是,当我有一个int列表并希望做一个“WHERE COL IN()”条件。在这种情况下,我将执行String.Format并在int上连接List以生成“IN”子句中的值。请注意,在这种情况下,我有一个int列表,所以这里没有SQL注入的机会。

我总是将String.Format用于动态SQL,比如指定表的名称,就像在你的例子中一样。


2
投票

我在评论中略微谈到了这一点,但我也会在这里发布一个答案。

参数化(在我看来)始终是要走的路,因为它确保了查询的“安全性”(注入参数化查询更加困难/不可能),并且还允许重用查询计划,这也可以是非常有益。

但是,对于您所拥有的内容,您无法按预期参数化SQL。变量不能替换对象的名称(db<>fiddle)。要做到这一点,你需要动态SQL。

我不打算假装我知道C#,但是,对于你拥有的东西,我不会,这意味着你有一个类似于“某事”的查询:

using (SqlCommand command = new SqlCommand(@"DECLARE @SQL nvarchar(MAX) = N'SELECT * FROM ' + QUOTENAME(@table) + N';'; EXEC sp_executesql @SQL;", connection))
{
    command.Parameters.AddWithValue("@table", table_name);

老实说,我不知道这是否适用于C#,但那将是你用(非常)简单术语参数化动态对象的方式。


0
投票

总是使用参数化查询只有一个sql计划实例(只是为了获得最佳性能)。

参数化查询看起来就像那个

select * from Table t where t.Id = @P1
© www.soinside.com 2019 - 2024. All rights reserved.