php数据库注入本质是用户输入被当作sql代码执行,主因是字符串拼接且未过滤转义或未用预处理语句,防御核心是禁用拼接、强制使用pdo/mysqli预处理及参数绑定。

PHP 中的数据库注入攻击,本质是把用户输入当成了可执行的 SQL 代码。最常见也最危险的情况,就是拼接 SQL 字符串时没做任何过滤或转义。
典型漏洞写法:字符串拼接 + 直接查询
比如登录验证逻辑中这样写:
$username = $_POST['username']; $password = $_POST['password']; $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$password'"; $result = mysqli_query($conn, $sql);
攻击者只要在用户名里填:' OR '1'='1,密码任意,最终 SQL 就变成:
SELECT * FROM users WHERE username = '' OR '1'='1' AND password = 'xxx'
由于 '1'='1' 恒成立,整个条件等价于 TRUE,结果查出所有用户(或第一条匹配记录),绕过身份验证。
立即学习“PHP免费学习笔记(深入)”;
更隐蔽的注入:数字型参数未类型校验
URL 中传 ID 参数时,开发者常以为“数字不会出问题”,于是这样写:
该软件是采用php+MySQL进行开发的微信分销系统。1、数据库连接地址:Public\Conf\config.php2、微信菜单修改:Public\Conf\button_config.php,然后“微信管理”-“菜单管理”-“重新生成菜单”。另下面三行代码请修改:$link_config (还没有关注的,引导关注,点击“立即关注”进入微信文章)$config_good_pic (购买时,页面上
$id = $_GET['id']; $sql = "SELECT * FROM articles WHERE id = $id";
但攻击者访问:?id=1 UNION SELECT username,password FROM users,SQL 就变成:
SELECT * FROM articles WHERE id = 1 UNION SELECT username,password FROM users
直接拖库。根本原因在于:没强制转换为整型,也没使用参数化查询。
防御核心:永远不拼接 SQL
- 用预处理语句(Prepared Statements)——PDO 或 MySQLi 都支持 bindParam / bindValue
- 对数字型参数,用 (int) 或 intval() 强制转换,再参与查询(仅作辅助,不能替代预处理)
- 避免使用 mysql_* 函数(已废弃且无预处理支持),改用 MySQLi 或 PDO
- 关闭错误回显(display_errors = Off),防止泄露数据库结构
真实案例参考:某 CMS 后台 ID 注入导致管理员密码泄露
某 PHP 博客系统后台存在文章编辑接口:/admin/edit.php?id=5,代码未预处理,攻击者提交:
?id=5 AND (SELECT SUBSTR(password,1,1) FROM admin_users WHERE id=1)='a'
通过布尔盲注逐字符爆破,最终获取管理员哈希密码。该系统未启用 prepared statement,也未限制后台接口的请求来源和权限校验,导致攻击链完整闭环。
不复杂但容易忽略:只要用户输入进了 SQL 字符串,又没走参数绑定,就存在风险。










