参数化语句可以停止所有 SQL 注入吗?

新手上路,请多包涵

如果是,为什么还有这么多成功的 SQL 注入?仅仅因为一些开发人员太笨,无法使用参数化语句?

原文由 iceagle 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 634
2 个回答

我在对该问题的评论中发布的链接很好地解释了这个问题。我总结了我对为什么问题仍然存在的感受,如下:

  1. 刚入门的人可能对SQL注入一无所知。

  2. 有些人知道 SQL 注入,但认为转义是(唯一的?)解决方案。如果您对 php mysql query 进行快速 Google 搜索,出现的第一页是 mysql_query 页面,其中有一个示例显示将转义的用户输入插入到查询中。没有提到(至少我看不到)使用准备好的语句。正如其他人所说,那里有很多使用参数插值的教程,它仍然使用的频率并不奇怪。

  3. 对参数化语句的工作方式缺乏了解。有些人认为这只是一种逃避价值的奇特手段。

  4. 其他人知道参数化语句,但不要使用它们,因为他们听说它们太慢了。我怀疑很多人都听说过参数化语句的速度非常慢,但实际上并没有自己做过任何测试。正如比尔卡尔文在他的演讲中指出的那样,在考虑使用准备好的语句时,性能差异很少被用作一个因素。 一次准备,多次执行 的好处似乎经常被遗忘,安全性和代码可维护性的改进也是如此。

  5. 有些在任何地方都使用参数化语句,但会插入未经检查的值,例如表和列名称、关键字和条件运算符。动态搜索,例如允许用户指定许多不同的搜索字段、比较条件和排序顺序的搜索,就是最好的例子。

  6. 使用 ORM 时的错误安全感。 ORM 仍然允许对 SQL 语句部分进行插值 - 参见 5。

  7. 编程是一门大而复杂的学科,数据库管理是一门大而复杂的学科,安全性是一门大而复杂的学科。开发一个安全的数据库应用程序并不容易——即使是经验丰富的开发人员也可能会陷入困境。

  8. stackoverflow 上的许多答案都无济于事。当人们编写使用动态 SQL 和参数插值的问题时,通常缺乏建议使用参数化语句的响应。有几次,有人反驳了我使用准备好的语句的建议——通常是因为感知到的性能开销不可接受。我严重怀疑那些提出这些问题中的大多数的人是否处于准备参数化语句所花费的额外几毫秒将对他们的应用程序产生灾难性影响的位置。

原文由 Mike 发布,翻译遵循 CC BY-SA 3.0 许可协议

SQL 注入是更大的代码注入问题的一个子集,其中数据和代码通过同一通道提供,并且数据被误认为是代码。参数化查询通过使用关于什么是数据和什么是代码的上下文形成查询来防止这种情况发生。

在某些特定情况下,这还不够。在许多 DBMS 中,可以使用存储过程动态执行 SQL,从而在 DBMS 级别引入 SQL 注入缺陷。使用参数化查询调用这样的存储过程不会阻止过程中的 SQL 注入被利用。另一个例子可以在 这篇博文 中看到。

更常见的是,开发人员错误地使用了该功能。正确完成后,代码通常看起来像这样:

 db.parameterize_query("select foo from bar where baz = '?'", user_input)

一些开发人员会将字符串连接在一起,然后使用参数化查询,这实际上并没有做出上述数据/代码区分,从而提供我们正在寻找的安全保证:

 db.parameterize_query("select foo from bar where baz = '" + user_input + "'")

正确使用参数化查询可以提供非常强大但并非不可穿透的 SQL 注入攻击保护。

原文由 Daniel Crowley 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进