我正在审核其他开发人员编写的一些旧代码,我在登录页面上偶然发现了以下代码:
...
var sql = String.Format("SELECT * FROM Users WHERE Username = '{0}'", txtUsername.Text.Replace("'", "''"));
var command = new SqlCommand(connection, sql);
...
起初我认为它很容易受到SQL注入攻击,但经过一些测试后我无法破解它。在这种情况下,只是替换引号足以阻止SQL注入吗?
我不是要求最好的做法。我试图在txtUsername中输入一些东西来注入SQL并证明它是不够的。
答案 0 :(得分:2)
一般来说,是*。
使用proper escaping of input is a recommendation from OWASP as a valid approach to avoiding SQL Injection虽然它可以满足您的所有需求,但值得列出其首选项以避免SQL注入攻击:
正如您所看到的,正确转义输入在列表中排在第三位,但是出于所有意图和目的,它应该足以避免SQL注入。我个人并不是这种方法的大力倡导者,但这仅仅是我的观点。
建议:何时可以使用参数化
虽然使用引号可以提供帮助,但您应该考虑使用proper parameterization来利用.NET框架提供的一些内置保护来检查参数是否属于正确的类型等等。是一个选项:
// Define a parameter in your query using the @parameter format (or ? in OleDbConnections)
var sql ="SELECT * FROM Users WHERE Username = @username";
using(var command = new SqlCommand(connection, sql))
{
// Ensure your connection is open and other code here...
// Add your parameter
command.Parameters.AddWithValue("@username",txtUsername.Text);
// Any other logic here...
// Execute your query
using(var reader = command.ExecuteReader())
{
// Do your thing...
}
}
参数化不是选项时
如TomTom所述,在某些情况下,由于实施(即需要太多参数)或性能限制,参数化可能或可行。在这些情况下,OWASP建议使用stored procedures或您当前的escaping input技术,这意味着您可以依赖于使用引号,但要小心并考虑尽可能多地清理您的输入。
答案 1 :(得分:-1)
通常,最佳选择是练习使用参数化查询。这是SQL Injection的坚实第一道防线。
关于您的问题,MSDN网站上的这篇博客可能是一本很好的读物。
https://blogs.msdn.microsoft.com/sqlphp/2008/09/30/how-and-why-to-use-parameterized-queries/