MySQL之SQL-Column-Truncation(长字符截断)
字数 1267 2025-08-09 22:00:34
MySQL SQL-Column-Truncation(长字符截断)漏洞详解与防御
1. 漏洞概述
MySQL超长字符截断漏洞(SQL-Column-Truncation)是由于MySQL在特定模式下对超长数据处理的宽松行为导致的。当sql_mode未启用严格模式时,MySQL对插入超长值只会提示warning而非error,导致数据被静默截断,可能引发安全问题。
2. 漏洞原理
2.1 sql_mode模式说明
MySQL 5.0+支持三种主要模式:
-
ANSI模式:
- 宽松模式
- 不符合定义类型或长度的数据会被调整或截断保存
- 仅报warning警告
- 除数为0时用NULL代替
-
TRADITIONAL模式:
- 严格模式
- 错误数据无法插入,报error错误
- 用于事务时会回滚
-
STRICT_TRANS_TABLES模式:
- 严格模式
- 错误数据无法插入,报error错误
- 对事务表严格,非事务表部分情况宽松
2.2 默认行为问题
当sql_mode设置为default(未开启STRICT_ALL_TABLES或TRADITIONAL或ANSI)时:
- 插入超长数据不会报错
- 数据会被静默截断
- 仅产生warning警告
3. 漏洞复现
3.1 测试环境搭建
CREATE TABLE USERS(
id int(11) NOT NULL,
username varchar(7) NOT NULL, -- 长度为7
password varchar(12) NOT NULL
);
3.2 测试案例
-
正常插入:
insert into users(id,username,password) values(1,'admin','admin');- 结果:成功插入,无警告
-
超长插入(右面三个空格,长度8):
insert into users(id,username,password) values(2,'admin ','admin');- 结果:成功插入,1个warning
-
超长插入(明显超长):
insert into users(id,username,password) values(3,'admin x','admin');- 结果:成功插入,1个warning
3.3 查询验证
select username from users;
输出:
admin
admin
admin x
长度验证:
select length(username) from users where id = 1; -- 5
select length(username) from users where id = 2; -- 7
select length(username) from users where id = 3; -- 7
3.4 安全问题演示
查询用户名为'admin'的用户:
select username from users where username='admin';
输出:
admin
admin
admin x
安全问题:攻击者可注册类似"admin "的用户名,绕过系统对"admin"用户的权限检查。
4. 漏洞利用场景
- 权限绕过:攻击者注册与管理员用户名相似但带空格或特殊字符的账号
- 数据混淆:导致系统对用户身份识别混乱
- 逻辑绕过:利用截断特性绕过某些输入验证
5. 防御措施
5.1 修改sql_mode
在配置文件中添加以下任一设置:
-
添加TRADITIONAL:
SET sql_mode='TRADITIONAL'; -
添加STRICT_TRANS_TABLES:
SET sql_mode='STRICT_TRANS_TABLES';
5.2 配置建议
推荐在my.cnf/my.ini中永久配置:
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
5.3 其他防御措施
- 应用层验证数据长度
- 使用预处理语句
- 对用户名等关键字段进行规范化处理(如去除首尾空格)
6. 严格模式详解
启用严格模式后,MySQL会:
- 拒绝插入超长数据
- 产生error而非warning
- 对于事务表会回滚操作
- 非事务表会部分执行
7. 受影响系统
- 使用MySQL且未配置严格模式的系统
- 依赖MySQL默认配置的应用
- 未对输入进行严格长度检查的Web应用
8. 总结
MySQL的SQL-Column-Truncation漏洞源于宽松的数据处理策略,通过配置严格的sql_mode可以彻底解决此问题。对于安全要求高的系统,建议始终启用STRICT_TRANS_TABLES或TRADITIONAL模式,并在应用层实施额外的输入验证。