PHP - PDO 引用是不是对 SQL 注入安全?

Posted

技术标签:

【中文标题】PHP - PDO 引用是不是对 SQL 注入安全?【英文标题】:PHP - Does PDO quote safe from SQL Injection?PHP - PDO 引用是否对 SQL 注入安全? 【发布时间】:2014-03-30 17:57:27 【问题描述】:
$id  = trim((int)$_GET['id']);
$sql = 'SELECT * FROM users WHERE id = ' . $db->quote($id) . ' LIMIT 1';
$run = $db->query($sql)->fetch();

PDO 的引用方法作为准备好的语句是否安全?或者我必须在我的脚本中一直使用准备好的语句?

【问题讨论】:

【参考方案1】:

基本上quote() 作为准备好的语句是安全的,但它取决于quote() 的正确实现,当然也取决于它的后续使用。此外,为了回答这个问题,还必须考虑使用的数据库系统/PDO 驱动程序的实现。

虽然准备好的语句可以成为底层数据库协议(如 mysql)的一个特性,然后将在数据库服务器上“准备好”(服务器站点准备 ),它不一定必须也可以在客户端站点上解析(客户端站点准备)。

在 PDO 中,这取决于:

驱动程序/数据库系统是否支持服务器端预处理语句? PDO::ATTR_EMULATE_PREPARES 必须设置为 false(如果驱动程序支持,则默认设置)

如果不满足其中一个条件,PDO 会退回到客户端站点准备,再次在后台使用quote() 之类的东西。


结论:

使用准备好的语句并没有什么坏处,我鼓励你使用它们。即使您明确使用PDO::ATTR_EMULATE_PREPARES 或您的驱动程序根本不支持服务器站点准备,准备好的语句将强制执行一个工作流,其中引用不能被忘记是安全的。另请检查@YourCommonSense 的答案。他对此进行了详细说明。

【讨论】:

【参考方案2】:

技术上 - 是的。

但是,这意味着您正在手动格式化您的值。而且手动格式化总是比准备好的语句更糟糕,因为它会使代码臃肿并且容易出现愚蠢的错误和混乱。

手动格式化的主要问题 - 它是可拆卸。意味着它可以在远离实际查询执行的地方执行。在哪里可以忘记,省略,混淆等等。

【讨论】:

【参考方案3】:

在 int 上使用 trim 有什么意义。然后引用该值?既然你有整数值,那么就这样使用它

$sql = 'SELECT * FROM users where id = ' . $id . ' LIMIT 1';

不要盲目地引用所有内容,只需注意变量的类型,并确保你没有做像 $id = trim((int)$_GET['id']); 这样的愚蠢事情,而 $id = (int)$_GET['id']; 就绰绰有余了

如果您不确定自己能否成功,请使用准备好的语句。但请注意你在编码什么

【讨论】:

以上是关于PHP - PDO 引用是不是对 SQL 注入安全?的主要内容,如果未能解决你的问题,请参考以下文章

PDO(PHP Data Object),Mysqli,以及对sql注入等问题的解决

我的 PDO 查询对 SQL 注入安全吗?

mysql注入问题

如果 PDO 和 mysqli 不可用,使用 mysql_* 函数是不是安全?

PHP常见安全问题及解决方法

你应该这个姿势学习PHP