我一直在寻找如何最好地防止PHP / mysql中的sql注入,而不仅仅是使用mysqli / mysql真正的转义,因为阅读这个Is mysql_real_escape_string enough to Anti SQL Injection?
我见过这个非常好的帖子How can I prevent SQL injection in PHP?
我用来在桌面/内部工具上做很多ms sql server的东西,我们总是编写存储过程来防止这种情况所以我在PHP / mysql中使用PDO http://php.net/manual/en/pdo.prepared-statements.php读取等效的东西
在上面有一行:
不需要引用准备语句的参数;驱动程序自动处理这个 . 如果应用程序专门使用预准备语句,开发人员可以确保不会发生SQL注入(但是,如果使用非转义输入构建查询的其他部分,仍然可以进行SQL注入) .
我一直认为PDO可以防止SQL注入攻击,所以任何人都可以从安全的角度提供PDO不足的实例吗?
2 回答
您仍然可以从存储过程中获取SQL注入,这些存储过程在内部使用PREPARE语法(在MySQL中)来创建动态SQL语句 .
这些需要非常小心,必要时使用QUOTE() .
理想情况下,我们不需要在存储例程中使用PREPARE,但在某些情况下,它很难避免:
在MySQL 5.5之前,LIMIT子句不能使用非常量值 .
IN()子句中使用的列表不能(合理地)参数化,因此如果使用此模式,则需要使用动态SQL
有时需要使用动态生成的ORDER BY子句 .
等等
在需要使用PREPARE的情况下,我会按优先顺序推荐:
如果某些东西是INT类型(等),它不容易受到SQL注入的影响,您可以将该值放入查询中而不会出现问题(例如,对于LIMIT)
字符串值可以在EXECUTE之前放入@variable,也可以传入EXECUTE子句
需要检查列表值(例如IN())的有效性 .
最后,QUOTE()可用于引用字符串值,这在某些情况下很有用
这不是您使用的结构(存储过程,预处理语句等),而是决定性的,但是您是否在任何时候使用 unchecked user input 将SQL连接在一起 . 例如,您可以从存储过程中执行动态SQL,在这种情况下,危险仍然存在 .
最简单的方法(从注入避免的角度来看)是使用带有限制变量的SP或PS:不需要检查它们,因为它们将被识别为在预定义占位符内的值 .