SQL注入漏洞

时间:2015-05-26 11:29:38

标签: c# sql-server sql-injection

我正在开发一个客户端已在代码中报告SQL注入漏洞的项目。这是我的代码......

1 public int ExecuteNonQuery(string query, SqlParameter[] parameters)
2 {
3   using (SqlCommand command = CreateCommand(query, parameters))
4   {
5       int rowsAffected = command.ExecuteNonQuery();
6       return rowsAffected;
7   }
8 }

CreateCommand方法为

private SqlCommand CreateCommand(string commandText, SqlParameter[] parameters)
{
    SqlCommand retVal = this.connection.CreateCommand();
    retVal.CommandText = commandText;
    retVal.CommandTimeout = this.commandsTimeout;
    retVal.Parameters.AddRange(parameters);
    return retVal;
}

该缺陷报告在第3行。我无法理解这里发生了什么样的攻击,因为这是一个控制台应用程序。但我必须修复这个缺陷,而且我不知道如何修复它。

查询

@"delete from {0} where runId in 
( select runId from {0}
  inner join 
    ( select sId as sId_last,
        wfId as wfId_last,
        max(runId) as runId_last from {0} where endTime is NULL
        group by sId, wfId ) t1
  on endTime is NULL and sId = sId_last and wfId = wfId_last
  and (runId <> runId_last or startTime < @aDateTime)
)";

帮助表示感谢。 感谢。

3 个答案:

答案 0 :(得分:5)

代码是无注入的...但请注意,调用ExecuteNonQuery的方法可以通过组合字符串来构建query

当您执行以下操作时会发生注射攻击:

string name = ...; // A name selected by the user.
string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";

因此,当您使用外部来源的文本撰写查询时。

请注意,更精细的注入攻击可能是多层次的:

string name = // The result of a query to the db that retrieves some data
              // sadly this data has been manipulated by the attacker

string query = "SELECT * FROM MyTable WHERE Name = '" + name + "'";

通常,您不需要用户界面来引起注入攻击......

您可以从网站/数据库中查询某些内容,并使用未经过验证的结果来查询数据库(如上例所示),从而导致注入攻击......或者甚至使用配置文件的内容可以导致注入攻击:修改配置文件所需的权限可能与在数据库上执行操作所需的权限不同,恶意用户可以拥有修改配置文件但不能直接访问数据库的权限。因此他可以将该程序用作对抗DB的特洛伊木马。

关于查询的

该查询的弱点(即字符串的组合)在于如何计算{0}。它是在一组固定字符串中选择的字符串吗?类似的东西:

string tableName;

if (foo)
   tableName = "Foo";
else if (bar)
   tableName = "Bar";

还是更受用户控制的东西?

如果表名在代码中是固定的,则不应该有任何注入攻击。如果从一些用户输入/用户可以访问的其他表中“提取”表名,我们将回到之前显示的问题。

答案 1 :(得分:2)

您已经公开了public方法,任何允许执行任何SQL表达式的代码都可以访问该方法。

我会考虑将该方法更改为internalprivate,以便不只是任何代码都可以调用该方法。

答案 2 :(得分:2)

第3行:

 using (SqlCommand command = CreateCommand(query, parameters))

此行中都有查询和参数。

尝试验证输入时不应阻止SQL注入;相反,该输入应在传递到数据库之前正确转义。

如何完全转义输入取决于您使用什么技术与数据库连接。

  

使用预准备语句和参数化查询。这些是SQL   发送给数据库服务器并由其解析的语句   与任何参数分开。这样就不可能了   攻击者注入恶意SQL。

Lesson on SQL injection供您参考。link2