我们正在讨论在我们的代码中使用参数化的 sql 查询。我们在讨论中有两个方面:我和其他一些人说我们应该始终使用参数来防止 sql 注入以及其他认为没有必要的人。相反,他们希望在所有字符串中用两个撇号替换单个撇号,以避免 sql 注入。我们的数据库都在运行 Sql Server 2005 或 2008,我们的代码库在 .NET framework 2.0 上运行。
让我在 C# 中给你一个简单的例子:
我希望我们使用这个:
string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe
而其他人想要这样做:
string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?
其中 SafeDBString 函数定义如下:
string SafeDBString(string inputValue)
{
return "'" + inputValue.Replace("'", "''") + "'";
}
现在,只要我们在查询中的所有字符串值上使用 SafeDBString,我们就应该是安全的。对?
使用 SafeDBString 函数有两个原因。首先,这是自石器时代以来的方式,其次,由于您看到在数据库上运行的精确查询,因此更容易调试 sql 语句。
那么。我的问题是使用 SafeDBString 函数是否真的足以避免 sql 注入攻击。我一直在尝试找到违反此安全措施的代码示例,但我找不到任何示例。
有没有人可以打破这个?你会怎么做?
编辑: 总结到目前为止的答复:
- 还没有人找到绕过 Sql Server 2005 或 2008 上的 SafeDBString 的方法。这很好,我想?
- 一些回复指出,使用参数化查询可以提高性能。原因是查询计划可以重复使用。
- 我们也同意使用参数化查询可以提供更易于维护的可读代码
- 此外,始终使用参数比使用各种版本的 SafeDBString、字符串到数字的转换和字符串到日期的转换更容易。
- 使用参数,您可以获得自动类型转换,这在我们处理日期或十进制数字时特别有用。
- 最后:不要像 JulianR 所写的那样尝试自己做安全工作。数据库供应商在安全性上花费了大量时间和金钱。我们没有办法做得更好,也没有理由尝试做他们的工作。
因此,虽然没有人能够破坏 SafeDBString 函数的简单安全性,但我得到了许多其他好的论据。谢谢!