SQL注入是PHP应用中最危险的漏洞之一,攻击者通过构造恶意SQL语句,绕过身份验证、窃取数据甚至删除整个数据库。根本原因在于将用户输入直接拼接到SQL查询中,未做任何安全处理。
最可靠的方法是使用PDO或MySQLi的预处理语句(Prepared Statements)。它将SQL逻辑与参数严格分离:先编译语句模板,再安全绑定变量。例如PDO中调用prepare()和bindValue(),数据库引擎会把参数视为纯数据,绝不会当作SQL代码执行。

2026AI生成图像,仅供参考
严禁使用过时的mysql_函数,它们已被废弃且不支持预处理。即使使用mysqli,也必须显式调用prepare()和bind_param(),而非简单的mysqli_query()拼接字符串。字符串型参数需加引号、数字型参数需类型校验——这些都由预处理自动完成,无需手动转义。
mysql_real_escape_string()或addslashes()等“转义”方案已被证明存在绕过风险,尤其在多字节编码或宽字符场景下可能失效。它们只是补丁式防御,无法替代预处理机制的语义隔离。
对于动态表名、列名等无法参数化的部分,必须采用白名单严格限制。例如用户选择排序字段时,只允许’username’、’created_at’等预定义值,通过in_array()校验后才参与拼接,绝不可接受任意输入。
错误信息暴露是重要隐患。生产环境必须关闭display_errors,并将error_reporting设为0,避免泄露数据库结构、路径等敏感细节。应记录错误到日志而非返回给用户。
权限最小化原则同样关键:数据库连接账号仅授予业务必需的权限,如只读接口就禁用INSERT/UPDATE/DELETE;避免使用root或sa等高权限账户。配合Web服务器配置(如禁用PHP的allow_url_include),形成纵深防御。
安全不是一次性配置,而是贯穿开发流程的习惯。每次接收$_GET、$_POST、$_COOKIE或$_SERVER中的值进入SQL前,都应自问:“这段输入是否经过预处理?是否可能成为代码?”定期用SQLMap等工具扫描、结合代码审计,才能守住数据生命线。