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注入等问题的解决