【问题标题】:How can this SQL query code be broken/exploited by user input? [duplicate]用户输入如何破坏/利用此 SQL 查询代码? [复制]
【发布时间】:2010-03-04 14:37:24
【问题描述】:

可能重复:
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 之前是未经过滤的,并且忘记密码似乎是以纯文本形式存储的。

永久支持它的解决方案很明显——使用位置参数——但我需要一些弹药来向管理层展示为什么/如何这段代码不安全,因此可以分配时间/$ 来修复它。

注意:我假设这可以被破坏,但实际上可能并非如此。我不是 SQL 超级明星。

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

【问题讨论】:

  • 如果您还没有阅读,也值得在这里阅读:stackoverflow.com/questions/139199/…
  • @Nick:谢谢,我没看到那个。我将把这个问题作为重复问题结束。
  • 应作者要求关闭。

标签: sql database sql-injection database-agnostic


【解决方案1】:

它可以被反斜杠利用。

password = foo\' OR 1=1 --

变成:

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

查询:

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

--是本例中的注释标记。

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

【讨论】:

  • 我不能说其他数据库,但反斜杠在 MSSQL 中似乎不是转义字符,而只是按字面意思使用。您的示例将仅搜索 'foo\' OR 1=1 -- 的密码
【解决方案2】:

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

【讨论】:

  • 它很容易受到攻击。该示例不使用任何参数绑定。
猜你喜欢
  • 2011-12-16
  • 2021-10-01
  • 2020-03-29
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 2015-05-11
相关资源
最近更新 更多