Sql注入 - 以下是开放攻击吗?

时间:2015-01-13 09:42:15

标签: c# mysql asp.net security stored-procedures

我最近开始在一家对SQL注入攻击持开放态度的公司工作。因为他们旁边根本没有输入卫生设施。

在指出问题后,我的任务是修复它。

通常这很容易,用SQLParamater对象替换裸变量。 但是,我发现了一些让我感到疑惑的奇怪的代码用法。

我的前任似乎一直在使用存储过程和驻留在代码中的一些SQL。然而,在一个地方,他似乎将两者结合起来。

他使用一些裸变量动态构建SQL,然后将生成的SQL作为参数传递给存储过程。

我想知道这个的安全性,将实际的SQL传递作为参数清理它还是我必须重新设计存储过程?

这是他正在做的事情的一个(大大简化)片段:

DataSet ExecuteQuery(string unsanitizedInput)
{
    string dynamicSQL = "WHERE column = " + unsanitizedInput;
    MySqlParameter param = new MySqlParameter("param1", dynamicSQL);
    string procname = "StoredProc_Name";
    DataSet ds = new DataSet();

    using (MySql.Data.MySqlClient.MySqlDataAdapter adapter = new MySql.Data.MySqlClient.MySqlDataAdapter(procname, DataUtils.ConnectionStrings["string"]))
    {
        adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
        adapter.SelectCommand.Parameters.Add(param);
        adapter.Fill(ds);
    }
    return(ds);
}

显然,对于许多参数,实际查询要复杂得多。但是这应该可以告诉你他正在做什么的原则。

我的问题是:上述安全吗? 即使将要注入存储过程的大得多的SQL语句的一部分,还是对未过滤的输入进行了清理吗?

我知道上面的内容很糟糕,几乎无法弄清楚SQL查询,但这就是我现在所处的位置。

所有建议都是适当的,并提前感谢。

1 个答案:

答案 0 :(得分:-1)

使用参数查询不提供针对slq注入攻击的完全保护,也不提供存储过程。我使用了两者,但在2010年,网站的数据库被two-step sql injection严重损害。

MSDN强烈建议检查任何输入文本是否有可疑元素。查看更多How To: Protect From SQL Injection in ASP.NET

我使用以下简单代码来检测sql注入(使用我已经记不住的一些好的源代码构建):

public static bool DetectSqlInjection(string Text)
{
    string CleanText = Text.ToUpper().Replace("/**/", " ").Replace("+", " ").Replace("  ", " ");

    string[] InjectionPatterns = { 
                                     "VARCHAR", 
                                     "EXEC", 
                                     "DECLARE", 
                                     "SELECT *", 
                                     "SELECT PASSWORD", 
                                     "SELECT USERNAME", 
                                     "$_GET",
                                     "NULL OR",
                                     "UNION ALL SELECT",
                                     "WAITFOR DELAY",
                                     "SELECT pg_sleep",
                                     "SHOW TABLES FROM"
                                     };

    foreach (string Pattern in InjectionPatterns)
    {
        if (CleanText.Contains(Pattern))
            return true;
    }

    return false;
}