首页 文章

在PHP中使用预准备语句/存储过程时,如何保护自己免受SQL注入?

提问于
浏览
2

我一直在寻找如何最好地防止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 回答

  • 1

    您仍然可以从存储过程中获取SQL注入,这些存储过程在内部使用PREPARE语法(在MySQL中)来创建动态SQL语句 .

    这些需要非常小心,必要时使用QUOTE() .

    理想情况下,我们不需要在存储例程中使用PREPARE,但在某些情况下,它很难避免:

    • 在MySQL 5.5之前,LIMIT子句不能使用非常量值 .

    • IN()子句中使用的列表不能(合理地)参数化,因此如果使用此模式,则需要使用动态SQL

    • 有时需要使用动态生成的ORDER BY子句 .

    等等

    在需要使用PREPARE的情况下,我会按优先顺序推荐:

    • 如果某些东西是INT类型(等),它不容易受到SQL注入的影响,您可以将该值放入查询中而不会出现问题(例如,对于LIMIT)

    • 字符串值可以在EXECUTE之前放入@variable,也可以传入EXECUTE子句

    • 需要检查列表值(例如IN())的有效性 .

    • 最后,QUOTE()可用于引用字符串值,这在某些情况下很有用

  • 3

    这不是您使用的结构(存储过程,预处理语句等),而是决定性的,但是您是否在任何时候使用 unchecked user input 将SQL连接在一起 . 例如,您可以从存储过程中执行动态SQL,在这种情况下,危险仍然存在 .

    最简单的方法(从注入避免的角度来看)是使用带有限制变量的SP或PS:不需要检查它们,因为它们将被识别为在预定义占位符内的值 .

相关问题