【问题标题】:Is PG::Connection#exec_params identical to using a prepared statement when it comes to protect against SQL Injections?在防止 SQL 注入方面,PG::Connection#exec_params 是否与使用准备好的语句相同?
【发布时间】:2017-07-05 23:24:45
【问题描述】:

admitted 准备好的语句为 SQL 注入提供了很好的保护,并且使用 PG::Connection#exec 手动将变量注入到 sql 查询中是邪恶的并且应该从不完成。

但是PG::Connection#exec_params 呢?它是否提供与预准备语句相同级别的 sql 注入保护?

如果它确实提供了针对 sql 注入的保护,它是始终正确还是只有在显式绑定参数时才正确?

【问题讨论】:

    标签: sql ruby postgresql pg


    【解决方案1】:

    TL;DR 是的。

    我不知道 Ruby 驱动程序的内部细节。我认为它可以使用三种策略。理论上只有一种可能会受到顶级 SQL 注入攻击(下文会详细介绍),但所有这些都可能容易受到较低级别的 SQL 注入攻击,就像准备好的语句一样。

    要理解这一点,您需要了解 PostgreSQL 如何执行查询:

    1. 查询被解析成解析树
    2. 参数用于规划查询
    3. 计划执行
    4. 提供数据以供返回。

    在准备好的语句中,计划被保存,但这并不是使它们安全的原因。使它们在顶级攻击方面安全的原因是参数与要解析的查询分开发送。

    第一个策略可能是服务器端准备好的语句。在这种情况下,计划将被保存并可能重复使用,这可能会产生不希望的(或理想的)性能影响。

    第二个是 PostgreSQL 协议允许单独发送查询和参数,即使不使用准备好的语句。这具有相同的安全优势,但不允许计划重用。查看代码,这看起来像是此方法的首选工作方式。

    第三个是您可以进行客户端转义。这仍然比您自己做的任何事情都更安全,因为它可能位于中心位置等。我知道 Perl 的 DBD::Pg 可以回退到这一点,但几乎从不这样做。我没有看到后备,但也许我错过了一个。

    所以一般来说,我会说是的,即使使用最差的方法,这确实提供了相当的好处。

    请注意,我一直在谈论顶级攻击。如果您在某个地方(例如从触发器)调用一个函数,那么您也可以在那里进行 SQL 注入。这发生在涉及动态 SQL 但通常不是问题的地方。上述方法都不能防止这种情况发生,因为计划阶段将作为上述执行阶段的子部分发生,并且始终填写参数。

    这就是为什么应用程序所有级别的良好编码实践都很重要的原因。

    【讨论】:

      猜你喜欢
      • 2012-08-07
      • 2012-07-12
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 2012-06-19
      • 2015-11-08
      相关资源
      最近更新 更多