Sql Injection - 以下是不是容易受到攻击?

Posted

技术标签:

【中文标题】Sql Injection - 以下是不是容易受到攻击?【英文标题】:Sql Injection - Is the following open to attack?Sql Injection - 以下是否容易受到攻击? 【发布时间】:2015-03-11 05:25:12 【问题描述】:

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

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

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

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

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

我想知道它的安全性,是否将实际 SQL 作为参数传递来对其进行清理,或者我是否必须重新设计存储过程?

这是他正在做的一个(大大简化的)sn-p:

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 或 1 =1),那么是的,它可以被攻击。 Where 子句将被绕过。 我认为最好的方法是使用参数化查询。并在处理之前将输入验证为查询。如果我们能找到某些类型的 sql 注入语句,则避免该输入。 您没有显示存储的过程,但我假设如果动态 SQL 被传递给它,那么过程正在使用代码构建查询然后执行它(例如,EXECUTE command 在 T -SQL)。在这种情况下,它仍然会受到 SQL 注入攻击。 感谢 cmets。是的,他在动态构建查询后使用“EXECUTE”,他作为参数传递的SQL通常是代码中动态生成的一整套条件子句。我会发布完整的查询,但它大约有 1000 行长,因为我很确定我的前任缺乏理智。我想这意味着我应该安全地重写它。再次感谢 cmets 伙计们,如果您发布答案,我会正确标记... 由于您不能将WHERE 子句作为参数传递,我对这个问题的回答是:不,它既不安全,也不能正常工作。 唯一 可以工作的方式是 SQL 语句是在存储过程中连接的字符串,然后使用 exec 或其他方式执行。这是你能做的最糟糕的事情。 【参考方案1】:

带参数的查询不提供针对 slq 注入攻击的全面保护,也不提供存储过程。两者我都用过,但在 2010 年被站点的 db 严重伤害了 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;

【讨论】:

您正在推荐 2005 年 5 月以来的 .NET 2.0 指南?今天的建议是使用准备好的语句提供的参数化。 变化越多,它们就越保持不变。关于 sql 注入攻击,自 2005 年以来唯一的变化是它们的攻击变得更加全面且难以识别。我也相信参数化,直到 2010 年,当我明白参数化不是万能药,虽然是一种非常不愉快的体验。

以上是关于Sql Injection - 以下是不是容易受到攻击?的主要内容,如果未能解决你的问题,请参考以下文章

以下代码片段是不是容易受到 Rails 5 中 SQL 注入的影响?

这个查询是不是受到 sql 注入的保护? [复制]

这个参数化查询是不是对 SQL 注入开放?

SQL Server 全文搜索 CONTAINS() 是不是容易受到 SQL 注入的攻击?

这个 Python 代码是不是容易受到 SQL 注入的影响? (SQLite3)

参数化的 java 持久性查询是不是容易受到 sql 注入的影响?