admitted准备好的语句可以很好地防止SQL注入,并且使用PG::Connection#exec手动将变量注入到sql查询中 evil 并且应该从不完成。
但是PG::Connection#exec_params呢?它是否提供与sql注入相同级别的保护而不是预备语句?
如果确实提供了针对sql注入的保护,它是否总是正确的,或者只有在显式绑定参数时才会出现这种情况?
答案 0 :(得分:2)
TL; DR是的。
我不知道Ruby驱动程序的内部细节。我认为它可以使用三种策略。理论上只有一个可能是顶级SQL注入攻击(更多内容见下文),但所有这些攻击都可能容易受到较低级别的SQL注入攻击,就像准备好的语句一样。
要理解这一点,您需要了解PostgreSQL如何执行查询:
在准备好的陈述中,计划得以保存,但这并不是使他们安全的原因。使它们在顶级攻击中安全的原因是参数与要解析的查询分开发送。
第一个策略可能是服务器端准备的语句。在这种情况下,计划将被保存并可能被重复使用,这可能会产生不良(或理想)的性能影响。
第二,即使不使用预准备语句,PostgreSQL协议也允许单独发送查询和参数。这具有相同的安全性优点,但不允许重复计划。查看代码,这看起来是此方法的首选方式。
第三是您可以进行客户端转义。这比你自己做的更安全,因为它可能位于中心位置等等。我知道Perl的DBD :: Pg可以回到这个但几乎从不这样做。我没有看到后退,但也许有一个我错过了。
所以一般来说,我会说是的,即使使用最糟糕的方法,它确实提供了可比较的好处。
注意我一直在谈论顶级攻击。如果你在某个地方(例如从触发器)调用一个函数,你也可以在那里调用SQL。这涉及动态SQL涉及但通常不是问题。上述方法都不能防止这种情况,因为计划阶段将作为上述执行阶段的子部分发生,并且参数始终被填充。
这就是为什么应用程序的所有级别的良好编码实践都很重要。