MySQL注入漏洞防御,业务禁止拼接SQL语句强制预编译

MySQL注入漏洞防御的核心思路,是让SQL语句的结构与用户输入彻底分离。
所谓禁止拼接SQL语句,就是不要用字符串把用户参数直接接进SQL;
而强制预编译(预编译语句)则是把SQL模板先交给数据库解析,再把参数单独传入。
本文会从原理、代码示例、排查方法和验证步骤讲清楚。

为什么拼接SQL会成为注入漏洞?

只要用户输入被当成SQL代码的一部分,就会产生注入风险。
例如下面这段PHP代码:

$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];

如果id传入1 OR 1=1,实际执行的SQL就变成:

SELECT * FROM users WHERE id = 1 OR 1=1

这会绕过条件,把整张表的数据都查出来。
更极端的还可以用1; DROP TABLE users--直接删表。

结论:只要存在字符串拼接SQL,就存在可能的注入点,改造方向就是使用预编译。

强制预编译的正确写法:以PHP PDO为例

PDO的预处理写法如下:

$pdo = new PDO('mysql:host=127.0.0.1;dbname=test;charset=utf8', 'user', 'pass', [
    PDO::ATTR_EMULATE_PREPARES => false, // 关闭模拟预处理,使用MySQL本地预处理
]);
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(['id' => $id]);
$row = $stmt->fetch();

这里的SQL模板和参数分两次传给MySQL:数据库先解析模板,再把$id作为纯值绑定。
即使$id里包含SQL语句,也只会被当成字符串处理。PHP PDO 中设置ATTR_EMULATE_PREPARES => false,才能真正落到MySQL服务端预处理。

Java后端也需要用PreparedStatement

Java JDBC中,禁止使用Statement拼接字符串,应改用PreparedStatement:

String sql = "SELECT * FROM users WHERE id = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id); // 参数通过set方法绑定,不能直接拼进sql字符串
ResultSet rs = ps.executeQuery();

如果你在用MyBatis,也要注意:#{}是预编译占位符,${}是字符串拼接。
比如WHERE id = #{id}安全,而ORDER BY ${column}存在注入风险。MyBatis中#{}是预编译,${}是拼接;
动态表名、排序字段不能预编译,必须用白名单校验。

存量业务如何排查拼接SQL?

在代码仓库里全局搜索这些特征,重点检查:

  • 字符串拼接符号:PHP的., Java的+,以及concat、String.format等。
  • MyBatis XML里的${}写法。
  • 直接拼接在SQL后面的$_GET、$_POST、request.getParameter()。

Linux下可以这样在当前目录代码中搜索:

grep -rn "SELECT.*WHERE.*+" --include="*.php" --include="*.java" .
grep -rn "\${}" --include="*.xml" .

搜到后逐一改成预编译写法,不要只看报告。存量的每一个拼接点,都可能是攻击入口。

避坑与验证:这样测才算真正防御

改完代码后,在测试环境用下面的字符串尝试注入:

1' OR '1'='1
1"; DROP TABLE users; --

如果查询结果与正常输入完全一致,或直接报参数类型错误,说明拼接已被拦截。
如果出现了额外数据或SQL报错中的语法片段,说明还有拼接点没改干净。

另一个常见的坑是:预编译只能处理“值”,不能处理表名、列名、排序字段。
如果业务确实需要动态表名或排序,最稳妥的做法是做成白名单,只允许传入固定的几个值,其他一律拒绝。

如果你正在处理MySQL注入漏洞防御,业务禁止拼接SQL语句强制预编译,建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。

分享到:
上一篇
中间人劫持HTTPS,业务强制校验证书禁止insecure跳
下一篇
备份文件泄露风险,网站目录*.sql
1
系统公告

泽御云中秋国庆双节活动上线:新购8折,拼团3.99元起

尊敬的用户:
泽御云“月满中秋·礼贺国庆”双节活动现已开启,活动时间为2026年9月23日至10月10日。 活动期间可享以下福利:
1. 常规云服务器新购使用优惠码“泽御中秋国庆同乐”,符合条件的订单享8折优惠。
2. 香港精品云服务器5人拼团低至3.99元,部分4核4G套餐3人拼团年付388元,续费同价。
3. 新用户购买年付云服务器,符合活动规则可赠送2个月使用时长。
4. 老用户续费季度赠15天,续费年度赠2个月;活动期间升级配置免收配置迁移手续费。
5. 推荐好友成功下单,符合条件的推荐人可获赠7天服务器使用时长。
6. 活动期间享宕机补偿标准翻倍、简单网站迁移协助及技术工单优先处理权益。
温馨提示:优惠码不适用于拼团套餐、活动轻量产品、年付订单及续费订单;拼团套餐为独立特价活动,不与赠时类福利叠加。赠送时长不可折现、退款或跨账户转移,具体规则以活动页面说明为准。
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意