MySQL 8.0+默认禁用LOAD DATA LOCAL INFILE是因该功能允许服务端诱导客户端读取本地敏感文件(如/etc/passwd),构成高危安全风险;必须同时禁用服务端local_infile=OFF和客户端--local-infile=0才能彻底生效。

为什么LOAD DATA LOCAL INFILE默认被禁用
MySQL 8.0+ 默认关闭 local_infile,是因为该功能允许客户端从自己本地磁盘读取文件上传到服务端,攻击者一旦获得数据库连接权限,就可能读取客户端机器上的敏感文件(如 /etc/passwd、私钥等)。这不是“功能没开”,而是安全策略主动拦截。
检查当前local_infile状态是否生效
只查变量值不等于实际可用——必须同时验证服务端和客户端两层配置:
-
SELECT @@global.local_infile;返回OFF或0表示服务端已禁用 - 客户端连接时若未显式启用
--local-infile=1(命令行)或local_infile=True(Python MySQLdb/PyMySQL),即使服务端开着也无效 - 运行
SHOW VARIABLES LIKE 'local_infile';确认结果;如果返回空或NULL,说明服务端根本没加载该变量(常见于仅修改了[mysql]段而漏掉[mysqld])
永久禁用:改my.cnf并重启mysqld
临时 SET GLOBAL local_infile = OFF; 在重启后失效,必须写入配置文件。注意两个段落都要加:
- 在
[mysqld]段下添加:local_infile = 0(服务端拒绝所有LOCAL请求) - 在
[mysql]段下添加:local-infile = 0(客户端默认不携带LOCAL标志,避免误连) - CentOS 常见路径是
/etc/my.cnf;Ubuntu/Debian 多为/etc/mysql/mysql.conf.d/mysqld.cnf;Windows 是my.ini - 改完必须
sudo systemctl restart mysqld,reload不生效
验证禁用是否真正起效
别只信配置文件内容,要实测:
- 用普通用户登录:
mysql -u user -p(不加--local-infile) - 执行:
LOAD DATA LOCAL INFILE '/tmp/test.csv' INTO TABLE t; - 正确结果应为:
ERROR 1148 (42000): The used command is not allowed with this MySQL version - 如果报
ERROR 2068 (HY000): LOAD DATA LOCAL INFILE file request rejected,说明客户端和服务端都已拦截 - 若仍成功——检查是否用了
mysql --local-infile=1 -u ...连接,或服务端配置未生效(SELECT @@global.local_infile;是否真为0)
彻底禁用 LOCAL 导入不能只靠参数开关,还要确保没有用户被授予 FILE 权限(它控制的是服务端文件读取,和 LOCAL 是两套机制),否则攻击者可能绕过客户端限制,直接让服务端去读取服务器本地文件。











