【问题标题】:When to worry about SQL injection protection何时担心 SQL 注入保护
【发布时间】:2013-01-16 21:01:59
【问题描述】:

小背景:我是这家公司唯一的程序员。我正在使用预先存在的框架。

也就是说,该公司有一个 dll(Database.dll),其中包含“我需要的所有数据库交互”。例如,它有一个Query()Update()Insert() 等。现在,我正在编写的项目设置了对 Database.dll 的引用。我的项目接受零用户输入。最接近用户输入的是一个下拉框,用户可以从中选择一个日期。没有太多经验,我很好奇我是否还需要担心 SQL 注入?如果是这样,查询会写成这样

var query = string.Format("SELECT timestamp FROM table1 WHERE date = \"{0}\" 
                           AND measured_dist = bit_loc AND rop > 0" , Date))

作为参数化查询就足够了吗?请记住,所有查询执行都由预先存在的Query() 处理,我被告知我必须使用它,并且无法编辑。

编辑

这个程序是一个 WinForm 应用程序。

【问题讨论】:

  • 正确答案是“总是”。
  • 除非你在做一些不能参数化的事情,否则就让它参数化。抛开安全性不谈,您可能会获得性能提升:参数化将为您的 RDBMS 节省参数化查询本身以使其与执行计划相匹配的工作。客户端之一,您不需要分配/格式化大量字符串,代码更整洁等等。
  • 只要用户不能输入成为查询一部分的文本,那么您应该没问题。但是您在上面所做的不是“参数化查询”,而是一个 string.Format() 调用,并且不会为您提供任何防止注入的保护。例如,如果“日期”变量包含值:“12/12/12\”;DELETE * FROM table1;\“SELECT timestamp FROM table1 WHERE 1=1”;你会有麻烦的。
  • 关于现有的 Query 方法:谁说你“必须使​​用,不能编辑”不是做出技术决策的好人:每一个部分都是错误的。如果有帮助,我可以建议一些方法来轻松更改参数。
  • “Database.dll”听起来像是一场等待发生的灾难。只是好奇,是什么阻止了某人在他们自己的应用程序中使用它来清除您的数据库。例如,一个不开心的员工通常可能不会获得数据库访问权限?

标签: c# sql


【解决方案1】:

如 cmets 所述,答案是“始终”。因为向其中添加参数并正确执行它会如此容易,而不是串联:只需第一次正确执行即可。另外:您是否认为注入不是您显示的代码中唯一的问题?该代码也容易受到本地化/国际化的影响。对于在不同文化中配置 PC 的用户会发生什么?日期和数字会以不同的方式呈现 - 并且经常会中断。参数不会发生这种情况。另外:名称通常在:)中带有撇号

【讨论】:

  • @ Marc Gravell - 说得很好。我只是想问问那些事情。 +1
  • @MarcGravell:我正在查询的数据库的格式(YYYY-mm-dd)在每种情况下都是相同的,我格式化了我的Date 以适应它。根据我正在阅读的有关参数化查询的内容,当命令执行由另一种方法处理时是否可以这样做?我一直在阅读this,但似乎查询是在执行它的相同方法中创建的。
  • @MarcGravell - 这是一个 C# 本地应用程序。参数不够。需要有特定的用户和存储过程(这是用户唯一的访问权限),否则很容易在应用程序内部查看并获取连接字符串并前往城镇。
  • @TyrionLannister 如果日期存储在日期列类型中,则参数将转换为 SQL 兼容格式。如果他们有“非常具体的格式”,我会认为他们将日期存储为字符串,这很傻,很善良。
  • @Pete:它们实际上是date 对象。
【解决方案2】:

请扩展@KirkWoll 的非常有效的评论,任何时候您将任何用户输入(或自动来源的输入)合并到 SQL 语句中,都会使您的程序面临 SQL 注入的风险。

作为一项政策,您永远不应该使用任何此类输入构建自己的 SQL 语句。

始终清理输入并始终使用参数化查询作为抵御 SQL 注入的第一道防线。

如果你以前没看过,xkcd上有一个很棒的插图

http://xkcd.com/327/

【讨论】:

    【解决方案3】:

    鉴于这是一个 WinForms 程序,访问数据库的唯一安全方法是使用带参数的存储过程。然后创建一个有权访问这些 SP 的用户。其他任何东西都不安全。

    虽然带有参数的查询在与可能具有“攻击”输入的 Web 应用程序一起使用时可作为一种安全措施,但在与可以反汇编并重写为任何内容的本地应用程序一起使用时它们会失败。如果您不提供 SP 安全性,您将迷失方向。

    【讨论】:

      【解决方案4】:

      即使用户交互可能是下拉菜单,老练的攻击者也有可能插入不在选择列表中的值。所以是的,你仍然应该警惕 SQL 注入。

      【讨论】:

      • 甚至不是“老练”的攻击者。任何具有适度编程技能的人都可以查看 HTML 上的源代码,根据自己的喜好对其进行编辑,并使用它来代替原始 HTML。有一点技巧的人可以使用浏览器插件来半自动化这个过程。
      • 是的,我不清楚它是否专门针对 HTML 接口。 Bart 评论说,如果它是某种桌面应用程序,可能需要更多技巧。
      • 当然。使用 Spy++ 之类的东西,我可以获得下拉列表的窗口句柄并添加到支持列表框中。 msdn.microsoft.com/en-us/library/dd460756.aspx
      • @EricJ。如果你打算使用调试工具,为什么不直接用你想要的替换查询字符串呢?
      • @jimbojw:当然比使用 HTML UI 更难,但在精通此类事情的初级程序员的领域中(根据经验)。
      【解决方案5】:

      即使没有 SQL 注入之类的东西,我也会使用准备好的语句。它们只是更容易使用,在某些情况下,它们允许数据库缓存语句,下次使用时不必编译它。 Oracle 会这样,我认为 SQL Server 会,我不知道 MySQL 会不会。

      您应该始终假设存在黑客,即使在内部 Intranet 项目中,我使用准备好的语句并使用 nonce 来防止 CSRF。

      【讨论】:

        猜你喜欢
        • 2015-08-20
        • 2013-12-07
        • 2010-09-14
        • 2014-10-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-03
        相关资源
        最近更新 更多