我一直在研究如何最好地防止PHP / mysql中的sql注入,而不仅仅是使用mysqli / mysql真正的转义,因为阅读这个是mysql_real_escape_string足够的反SQL注入?
我已经看到这个非常好的线程如何在PHP中阻止SQL注入?
我用来在桌面/内部工具上做很多ms sql server的东西,我们总是编写存储过程以防止这种情况所以我在PHP / mysql中使用PDO读取等效的http://php.net/manual/en/pdo.prepared-statements.php
在上面有一行:
The parameters to prepared statements don't need to be quoted; the driver automatically handles this. If an application exclusively uses prepared statements, the developer can be sure that no SQL injection will occur (however, if other portions of the query are being built up with unescaped input, SQL injection is still possible).
我一直认为PDO可以防止SQL注入攻击,所以任何人都可以从安全的角度提供PDO不足的实例吗?
您仍然可以从存储过程中获取SQL注入,这些存储过程在内部使用PREPARE语法(在MySQL中)来创建动态SQL语句。
这些需要非常小心,必要时使用QUOTE()。
理想情况下,我们不需要在存储例程中使用PREPARE,但在某些情况下,它很难避免:
在MySQL 5.5之前,LIMIT子句不能使用非常量值。
IN()子句中使用的列表不能(合理地)参数化,因此如果使用此模式,则需要使用动态SQL
有时需要使用动态生成的ORDER BY子句。
等等
在需要使用PREPARE的情况下,我会按优先顺序推荐:
如果某些东西是INT类型(等),它不易受SQL注入的影响,您可以将值放入查询中而不会出现问题(例如,对于LIMIT)
字符串值可以在EXECUTE之前放入@variable,也可以传递给EXECUTE子句
需要检查列表值(例如IN())的有效性。
最后,QUOTE()可用于引用字符串值,这在某些情况下很有用
这不是您使用的结构(存储过程,预处理语句等),而是决定性的,但是您是否在任何时候使用未经检查的用户输入将SQL连接在一起。例如,您可以从存储过程中执行动态SQL,在这种情况下,危险仍然存在。
最简单的方法(从注入避免的角度来看)是使用带有限制变量的SP或PS:不需要检查它们,因为它们将被识别为在预定义占位符内的值。