如何通过用户输入破坏/利用此SQL查询代码?

时间:2010-03-04 14:37:25

标签: sql database sql-injection database-agnostic

  

可能重复:
  Can I protect against SQL Injection by escaping single-quote and surrounding user input with single-quotes?

我们有一个遗留应用程序不使用位置参数进行查询,并且到处都有SQL。决定(在我开始之前),由于用户输入可以包含撇号,因此应该为这些撇号手动转义每个字符串输入。

这是必要的原始代码(不是由我编写的),翻译成C#以便于消费:

private string _Escape(string input)
{
    return input.Replace("'", "''");
}

private bool _IsValidLogin(string userName, string password)
{
    string sql =
        string.Format
        (
            @"SELECT COUNT(*) FROM UserAccounts
                WHERE UserName = '{0}' AND Password = '{1}'",
            _Escape(userName),
            _Escape(password)
        );
    // ...
}

这看起来似乎可以在某种程度上被打破,但我不知道它是如何被用户输入利用的。假设用户输入未经过滤,直到达到_IsValidLogin,并忘记密码似乎以纯文本形式存储。

支持它的解决方案是显而易见的 - 使用位置参数 - 但是我需要一些弹药来向管理人员证明这个代码为什么/如何不安全所以可以分配时间/ $来修复它。 / p>

注意:我假设这可能会被打破,但事实上可能并非如此。我不是SQL巨星。

注2:我已将此问题表达为与数据库无关,但如果您可以将此代码用于某个引擎,我欢迎您的贡献。

3 个答案:

答案 0 :(得分:3)

可以用反斜杠来表示。

password = foo\' OR 1=1 --

变为:

password = foo\'' OR 1=1 --

查询:

"SELECT COUNT(*) FROM UserAccounts
                WHERE UserName = '{0}' AND Password = 'foo\'' OR 1=1 --'"

--此示例中是注释标记。

该解决方案假定程序仅过滤(重复)撇号。

答案 1 :(得分:1)

这是一篇非常好的文章:http://unixwiz.net/techtips/sql-injection.html

请参阅“查找表名称”。

答案 2 :(得分:0)

好吧,我看不出它的弱点。所以,让我们争论一个不同的原因,为什么它应该被改变 - 它是相当无比的。在MSSQL(我认为,大多数其他高端SQL服务器)中,解析查询,设计执行计划,然后存储查询和计划。如果再次请求exact查询副本,则使用保存的执行计划。参数不会影响这一点,因此如果您使用参数,它将重用计划;如果您嵌入文本,它永远不会。