取代行情足以防止SQL注入?

时间:2016-05-17 17:25:15

标签: c# sql sql-server sql-injection

我正在审核其他开发人员编写的一些旧代码,我在登录页面上偶然发现了以下代码:

...
var sql = String.Format("SELECT * FROM Users WHERE Username = '{0}'", txtUsername.Text.Replace("'", "''"));
var command = new SqlCommand(connection, sql);
...

起初我认为它很容易受到SQL注入攻击,但经过一些测试后我无法破解它。在这种情况下,只是替换引号足以阻止SQL注入吗?

我不是要求最好的做法。我试图在txtUsername中输入一些东西来注入SQL并证明它是不够的。

2 个答案:

答案 0 :(得分:2)

一般来说,是*。

使用proper escaping of input is a recommendation from OWASP as a valid approach to avoiding SQL Injection虽然它可以满足您的所有需求,但值得列出其首选项以避免SQL注入攻击:

  • 选项1:使用参数化查询
  • 选项2:使用存储过程
  • 选项3:转义所有用户提供的输入(您的方法)

正如您所看到的,正确转义输入在列表中排在第三位,但是出于所有意图和目的,它应该足以避免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/