2014-06-30 107 views
1

我使用PDO声明如下SQL注入:哪些语句可以防止较好SQL注入

select * from `admine_user` where `user_id` = ? and passw = ? 
$resultfm1 = DB::instance()->prepare($query)->execute 
(array($escapedid,$hashedpass))->fetchAll(); 

我想用

select * from `admine_user` where `user_id` = :user and passw = :pwd 
$resultfm1 = DB::instance()->prepare($query)->execute 
(array(":user"=>$escapedid,":pwd"=>$hashedpass))->fetchAll(); 

出上述声明这是更好地使用它可以有效防止SQL注入,因为现在我不能使用mysql_real_escape_string

+0

既防止.. – sectus

+0

感谢@sectus ..有人downvoted,我可以知道原因,并感谢谁upvoted的人。我认为,我们在这里学习 – Gags

+2

你应该确保你的准备不被模拟('$ con> setAttribute(PDO :: ATTR_EMULATE_PREPARES,false);') - [Read More。](http://stackoverflow.com/questions/ 8776344 /如何对 - 视图 - 查询错误在-PDO-PHP/8776392#8776392)。但是,两个查询都是一样的。 – Darren

回答

5

MySQL仅支持位置参数(?占位符),所以PDO内部共享在准备步骤中将命名参数转换为位置参数。

所以事实上,两种风格最终都会对MySQL做同样的事情。

此外,“模拟准备”实际上并没有在准备步骤中做任何事情,它只是保存查询字符串。当你执行时,你提供值,并将它们插入到查询中,然后提交给MySQL。如果您不信任此过程,请禁用模拟准备。

这并不是说PDO做任何不安全的事情,尽管早期版本的PDO有一些错误。

只要确保您使用的是当前版本的PDO(基本上任何PHP 5.3或更新的版本),然后这两种样式都可以像安全一样安全。

尽管我写这篇文章后可能发生的任何回归bug ......

+1

+1这正是你需要知道OP的答案。 – Darren

+0

+1我不知道PDO将命名参数转换为位置。这是否意味着使用位置参数而不是命名? –

+0

是的.. @bill karwin ..我只使用PHP 5.3 – Gags