LOAD DATA LOCAL INFILE是MySQL提供的一个数据导入语句,支持客户端从自身所在的本地文件系统读取数据文件,然后将这些数据导入到MySQL服务端的指定表中。这个功能在批量导入本地数据到数据库时非常便捷,但如果缺乏安全限制,会带来严重的安全问题。

LOAD DATA LOCAL INFILE 的工作原理
普通的LOAD DATA INFILE语句是让MySQL服务端从自身的文件系统读取数据文件,而加上LOCAL关键字后,执行流程会发生变化:
- 客户端向服务端发送LOAD DATA LOCAL INFILE请求,同时指定要读取的本地文件路径
- 服务端收到请求后,会向客户端发送文件读取指令
- 客户端根据指令读取本地对应文件的内容,分段发送给服务端
- 服务端接收数据后,将数据写入到目标表中
这个流程的核心特点是,文件的读取操作发生在客户端侧,而服务端只是被动接收客户端发送的文件内容。
LOAD DATA LOCAL INFILE 的安全风险
该功能的安全风险主要来源于客户端对本地文件的读取权限没有被严格限制,常见的攻击场景有以下两种:
1. 敏感文件泄露
如果攻击者已经获取了数据库的查询权限,就可以构造恶意的LOAD DATA LOCAL INFILE语句,让客户端读取本地的重要文件,比如/etc/passwd、应用配置文件、SSH私钥等,然后将文件内容导入到攻击者可以访问的表中,从而窃取敏感信息。
示例攻击逻辑如下,假设攻击者已经可以控制客户端执行SQL语句:
-- 先创建一张用于接收文件内容的表
CREATE TABLE temp_file_content (
line_content TEXT
);
-- 让客户端读取/etc/passwd文件并导入到表中
LOAD DATA LOCAL INFILE '/etc/passwd'
INTO TABLE temp_file_content
FIELDS TERMINATED BY 'n';
-- 攻击者随后查询该表即可获取文件内容
SELECT * FROM temp_file_content;
2. 服务端伪造读取请求
即使客户端没有主动执行LOAD DATA LOCAL INFILE语句,恶意的MySQL服务端也可以在客户端连接后,伪造文件读取请求,让客户端读取本地任意文件并返回给服务端。这种情况在客户端连接不可信的MySQL服务端时非常容易发生。
--local-infile=0 配置的作用
--local-infile是MySQL的一个服务端配置项,用于控制是否允许使用LOAD DATA LOCAL INFILE功能,取值含义如下:
| 取值 | 含义 |
|---|---|
| 1(默认值) | 允许客户端使用LOAD DATA LOCAL INFILE功能,客户端可以读取本地文件导入到数据库 |
| 0 | 禁用LOAD DATA LOCAL INFILE功能,客户端执行相关语句时会直接返回错误 |
配置--local-infile=0后,不管客户端是否主动发起请求,还是服务端伪造读取请求,只要涉及LOCAL方式的文件读取,都会被服务端直接拒绝,从根源上切断了上述攻击路径。
如何配置 --local-infile=0
1. 临时配置(重启后失效)
如果需要临时生效,可以直接登录MySQL服务端执行以下命令:
-- 查看当前配置 SHOW VARIABLES LIKE 'local_infile'; -- 设置为0禁用功能 SET GLOBAL local_infile = 0;
2. 永久配置
如果需要永久生效,需要修改MySQL的配置文件,一般路径为/etc/my.cnf或者/etc/mysql/my.cnf,在[mysqld]区块下添加配置:
[mysqld] # 禁用LOAD DATA LOCAL INFILE功能 local-infile=0
修改完成后重启MySQL服务即可生效,不同系统的重启命令略有区别:
# CentOS系统 systemctl restart mysqld # Ubuntu系统 systemctl restart mysql
特殊情况的处理
如果业务确实需要使用LOAD DATA LOCAL INFILE功能,不能完全禁用,可以采取以下限制措施:
- 严格限制可以执行该语句的数据库账号权限,只给必要的业务账号开放权限
- 客户端连接时使用--local-infile=0参数,主动禁用自身的本地文件读取能力
- 避免连接不可信的MySQL服务端,防止服务端伪造读取请求
安全建议:如果业务没有明确的本地文件导入需求,优先配置--local-infile=0,这是成本最低且最有效的防护方式。
LOAD_DATA_LOCAL_INFILElocal-infile=0MySQL安全数据导入风险修改时间:2026-06-30 18:21:30