SQL注入是PHP应用中最古老也最危险的漏洞之一,攻击者通过构造恶意SQL语句,绕过身份验证、窃取数据甚至控制数据库服务器。防御的核心原则是:永远不信任用户输入,绝不拼接SQL。

AI设计,仅供参考
最可靠的防御手段是使用预处理语句(Prepared Statements)。PHP中PDO与MySQLi均原生支持。例如,PDO方式下,先定义含占位符的SQL模板(如“SELECT FROM users WHERE email = ?”),再绑定用户输入参数执行。数据库引擎将SQL结构与数据严格分离,输入内容仅被视作值而非代码,从根本上杜绝注入可能。
严禁使用mysql_系列已废弃函数,也禁用字符串拼接动态SQL。即便对输入做str_replace过滤关键词、或用addslashes转义单引号,也都形同虚设——攻击者可利用宽字节、编码绕过、或使用UNION SELECT等高级技巧轻松突破。
参数化不仅限于WHERE条件,INSERT、UPDATE、ORDER BY等位置同样适用。对于必须动态的字段名或表名(如多租户场景下的分表逻辑),应采用白名单校验:提前定义允许的合法标识符数组,用in_array()严格比对,拒绝一切未授权名称。
数据库连接需遵循最小权限原则。应用账号不应拥有DROP、CREATE、FILE等高危权限,通常仅授予SELECT、INSERT、UPDATE、DELETE及必要索引操作权限。生产环境关闭错误显示(display_errors=Off),避免泄漏SQL结构、路径等敏感信息。
定期使用OWASP ZAP或sqlmap进行自动化扫描,并结合人工代码审计,重点检查所有$_GET、$_POST、$_COOKIE、$_SERVER等外部数据进入SQL前的处理逻辑。引入类型声明(如intval()、filter_var($input, FILTER_SANITIZE_EMAIL))作为辅助校验,但不可替代预处理。
安全不是功能开关,而是贯穿开发周期的习惯。每次编写数据库交互代码时,自问:“这段SQL会不会把用户输入当命令执行?”答案若为“会”,立即重构为参数化查询——这才是真正牢靠的第一道防线。