大数跨境
0
0

MySQL 中常见的注入漏洞及修复

MySQL 中常见的注入漏洞及修复 Linux运维技术之路
2025-11-30
9
导读:MySQL 中常见的注入漏洞及修复SQL 注入是所有数据库安全问题中出现频率最高的漏洞之一。

 










 

MySQL 中常见的注入漏洞及修复

SQL 注入是所有数据库安全问题中出现频率最高的漏洞之一。
只要你的系统和 MySQL 交互,一旦输入过滤不到位、SQL 构造不安全,就可能被入侵。

  • • MySQL 中常见的注入方式有哪些?
  • • 每种注入背后的原理是什么?
  • • 如何正确修复,做到企业级防护?

非常适合做安全排查、代码 Review、面试准备。


一、什么是注入漏洞?(一句话解释)

将用户输入拼接到 SQL 中,使输入被当作 SQL 代码执行。

例:


   
    
   SELECT * FROM users WHERE name = '$name';

攻击者输入:


   
    
   ' OR '1'='1

SQL 变成:


   
    
   SELECT * FROM users WHERE name = '' OR '1'='1';

恒真 → 直接绕过登录。


二、MySQL 常见的注入漏洞类型(完整列表)

下面是业务系统中最常见的 7 类注入漏洞👇


1)数字型注入(最容易被忽略)

错误代码:


   
    
   SELECT * FROM products WHERE id = $id;

攻击者输入:


   
    
   1 OR 1=1

执行:


   
    
   SELECT * FROM products WHERE id = 1 OR 1=1;

→ 全表泄漏。

✅ 修复方式

使用参数化:


   
    
   WHERE id = ?

并验证参数是否为数字。


2)字符型注入(登录最常见)

错误代码:


   
    
   SELECT * FROM users WHERE name = '$name' AND pwd = '$pwd';

攻击者:


   
    
   name = admin
pwd  = ' OR '1'='1

绕过验证。

✅ 修复方式

✔ 使用预编译 PreparedStatement
✔ 禁止字符串拼接
✔ 对输入做长度、字符规则校验


3)LIKE 模糊查询注入(经常被漏掉)

错误代码:


   
    
   SELECT * FROM products WHERE title LIKE '%$keyword%';

攻击者输入:


   
    
   %' UNION SELECT user, password FROM users --

为什么危险?

LIKE '%xxx%' 中间内容无法用引号隔离 → 极易被注入。

✅ 修复方式

✔ 参数化:LIKE CONCAT('%', ?, '%')
✔ 过滤 LIKE 特殊字符:% _
✔ 限制最大长度(防止超长 payload)


4)ORDER BY / GROUP BY 注入(少见但危害大)

错误代码:


   
    
   SELECT * FROM orders ORDER BY $field;

攻击者:


   
    
   field = id desc; drop table users;

→ 排序字段本应是固定字段,但开发者没做校验。

✅ 修复方式

✔ ORDER BY / GROUP BY 必须使用 白名单


   
    
   $allowed = ["id", "price", "create_time"];
$field
 = in_array($field, $allowed) ? $field : "id";

绝对不能做参数化,因为参数化不支持字段名。


5)UNION 注入(数据泄漏最多)

示例:


   
    
   SELECT id, title FROM products WHERE id = '$id';

攻击者输入:


   
    
   -1 UNION SELECT user, password FROM users

要求:

  • • 列数要一致
  • • 类型要兼容

修复方式

✔ 参数化 + 类型校验
✔ 永不让用户控制完整 SQL 结构
✔ WAF 过滤 UNION、SELECT 等关键字


6)报错注入(能直接爆数据库结构)

利用 MySQL 错误函数:


   
    
   updatexml(), extractvalue(), floor(), exp()

错误 SQL:


   
    
   AND updatexml(1, concat(0x7e, database(), 0x7e),1)

数据库名称直接出现在错误信息中。

修复方式

✔ 隐藏数据库报错信息(统一友好提示)
✔ 正常业务绝不能直接暴露 SQL 错误
✔ 日志记录真实错误,但不展示给用户


7)二次注入(非常隐蔽)

场景:

  1. 1. 恶意代码先存入数据库(未触发注入)
  2. 2. 之后某个业务再次取出,并拼接进 SQL
  3. 3. 第一次输入安全,第二次触发漏洞

例:

数据库存了:


   
    
   1'; DROP TABLE users; --

之后在 “更新用户信息” 时拼接进 SQL → 直接被执行。

修复方式

✔ 所有从数据库读出的内容再次使用参数化
✔ 永不拼接 SQL
✔ 给字段做严格白名单校验


三、注入漏洞的终极修复策略

这里给你大厂统一标准👇


策略 1:永远使用预编译(Prepared Statement)

这是 最重要、防御力最高的方案

例(Java):


   
    
   String sql = "SELECT * FROM user WHERE name = ? AND pwd = ?";

例(PHP):


   
    
   $stmt = $pdo->prepare("SELECT * FROM user WHERE name = ? AND pwd = ?");

完全隔离 SQL 结构与参数 → 注入不可能成功。


策略 2:对输入做严格校验(白名单策略)

根据场景限制:

  • • 字段名用 白名单
  • • 数字用正整数校验
  • • 字符串使用正则,例如用户名:

   
    
   ^[a-zA-Z0-9_]{3,20}$

不要放任用户输入各种奇怪字符。


策略 3:限制数据库权限(不要用 root)

应用连接数据库必须使用“最小权限”账号:

  • • Web 端只授予 SELECT、UPDATE、INSERT
  • • 后台运维才能 DROP、ALTER
  • • 分库分表隔离敏感业务

即使发生注入,也能最大限度降低损害。


策略 4:隐藏数据库错误(防止报错注入)

线上不可出现:


   
    
   SQL syntax error near ...

应该使用统一错误码展示,实际错误写入日志。


策略 5:添加 WAF 防护

Web 防火墙可自动拦截:

  • • UNION SELECT
  • • OR 1=1
  • • SLEEP(1)
  • • /!/ 注释符
  • • Hex 编码

适合大型网站作为第二层防护。


**四、总结 **

MySQL 常见注入包括:数字型、字符型、UNION 注入、报错注入、盲注、二次注入、ORDER BY 注入等。
其根本原因是用户输入被当作 SQL 执行。

修复的核心策略是:
参数化(Prepared Statement) + 输入白名单 + 最小权限 + 错误隐藏 + WAF 防护。

实际开发中:
永远不要拼接 SQL,是所有 SQL 注入防护的终极方案。

 



 

 


往期回顾

【声明】内容源于网络
0
0
Linux运维技术之路
专注运维架构、高可用、高并发、高性能、大数据、容器化、数据库、python、devops等开源技术和实践的分享。
内容 347
粉丝 0
Linux运维技术之路 专注运维架构、高可用、高并发、高性能、大数据、容器化、数据库、python、devops等开源技术和实践的分享。
总阅读869
粉丝0
内容347