【问题标题】:SQL injection: isn't replace("'", "''") good enough?SQL 注入:replace("'", "''") 还不够好吗?
【发布时间】:2012-01-20 08:25:35
【问题描述】:

虽然我当然可以看到使用参数进行 SQL 查询的优势,尤其是在处理日期时间和类似的事情时,但我仍然不确定参数是否是防止 SQL 注入的唯一方法。
事实是,我继承了一个应用程序,它有类似的东西

"SELECT Field FROM Table WHERE Filter='"+userinput.Replace("'", "''")+"'"

到处都是。现在,虽然这些在我看来不是很愉快,而且我不介意重写它们,但我的问题是,我 需要 吗?尽我所能,我看不到用这个执行 SQL 注入的方法。

【问题讨论】:

  • 如果业界公认的最佳实践是使用参数化查询,具体来说,您不使用它们的原因是什么?
  • 这段代码是别人写的,就像我说的。我要为其添加一些功能。如果我还要在几十个地方更改程序的其余部分,在确定它的行为与现在相同之前,我需要进行大量测试。因此,如果没有像现在这样的危险,我不确定这是否值得。
  • 您必须权衡测试与有人窃取/破坏您的数据。
  • 并非所有 SQL 语句都是可参数化的,例如 set role "a@b.com"listen channel1,其中“a@b.com”或“channel”是您可能希望让用户设置的内容

标签: sql-server tsql


【解决方案1】:

不,这还不够。它会在紧要关头完成,但它是一个非常弱的替代方案,如果您的平台和/或 RDBMS 支持任一功能,则使用参数化查询或参数化存储过程会更好。

来自

OWASP's SQL Injection Prevention Cheat Sheet

...与使用参数化查询相比,这种方法是脆弱的。 仅应谨慎使用此技术来改造传统 以经济高效的方式编写代码。

下面还有更多

SQL injection — but why isn't escape quotes safe anymore?

Sql Injection Myths and Fallacies

SQL Injection after removing all single-quotes and dash-characters

【讨论】:

  • 我特别喜欢这个帖子:codeinsecurity.wordpress.com/2011/12/09/…
  • @Polynomial:该帖子不适用于此查询。在这里,用户输入不能在字符串中转义。
  • 我本来打算反对您的原始帖子,该帖子非常反对这种方法,但似乎做一些研究为您带来了更合理的观点:)。当然,这不是最好的方法,但如果它到位,我认为不需要完全重写所有数据访问,除非你有时间。
  • 请给出一些简单的理由/例子说明为什么它不够好,而不是提供替代建议..
  • 实际上,如果您知道您的数据库并且您的代码只会与该数据库系统对话,并且您仅在需要写入数据库时​​才转义,那么它可以正常工作,并且不需要其他字符串操作消除 SQL 注入。使用准备好的语句是一种很好的做法,这样您的代码就可以跨不同的数据库系统工作。
【解决方案2】:

是的,.Replace("'", "''") 停止 SQL 注入的程度与参数化相同。

仍然存在双重或反射注入。例如,您可以存储

'; delete from orders'

在评论字段中。如果部分数据库使用动态 SQL 中的注释字段,它可能会改为运行删除。

【讨论】:

  • 我不明白那个答案。您的输入示例如何成为 OP 问题的利用?他正在逃避单引号,所以我认为没有机会。
  • @SQLPolice:例如declare @sql nvarchar(max); select @sql = 'select ''' + Field + '''' from yourtable; exec (@sql);
  • 但 OP 正在转义所有单引号。请参阅replace声明。 sql字符串变成普通字符串,不会被视为可执行代码。
  • 你的第一句话:Yes, .Replace("'", "''") stops SQL injection to the same degree that parameterization does. 是完全不正确的,即使它是写出来的。
【解决方案3】:

如果用户只需要对数据进行只读访问,则让 UI 通过只有只读访问权限的 SQL 用户执行。只读不能保护您免受注入攻击 - 他们可以使用它来查看您不希望他们查看的数据,但他们不能使用注入来删除数据。

【讨论】:

  • 不错,但在这种情况下恐怕不适用。不过,我可以在任何下一个项目中记住它。
【解决方案4】:

我认为您在途中得到了关于为什么它还不够的答案,但您也遇到了有人忘记对字符串进行替换的问题。如果您“总是”使用参数,那么这不是问题。

【讨论】:

  • 我同意。你只需要在一个地方错过一个字符串替换,游戏就结束了。
【解决方案5】:

使用过程。

将语句转换为静态 SQL,将参数的值放入局部变量中。

这确实有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-13
    • 2011-03-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    相关资源
    最近更新 更多