设为 null 才算真正禁用,因为只有 mysql 8.0.17+ 支持 secure_file_priv = null,此时 select ... into outfile 和 load data infile 直接报错,彻底切断功能。

为什么设为 NULL 才算真正禁用
secure_file_priv = NULL 是 MySQL 8.0.17+ 唯一能让 SELECT ... INTO OUTFILE 和 LOAD DATA INFILE 直接报错的配置值。它不是“限制路径”,而是彻底切断能力——返回 ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option...,连语法检查都跳过。设为空字符串 '' 或具体路径(如 /var/lib/mysql-files/)仍允许导出,只是路径受限;而设为 NULL 后,哪怕用户有 FILE 权限,语句也根本执行不起来。
必须同时撤回 FILE 权限
只改 secure_file_priv 不够。只要用户还持有 FILE 权限,就可能通过其他方式绕过(比如配合 UDF、日志写入等)。所以得同步执行:
-
REVOKE FILE ON *.* FROM 'user'@'host';—— 注意必须是*.*,db.*无效 - 若用户属于角色(MySQL 8.0+),还要查
SHOW GRANTS FOR ROLE 'role_name';并对角色同样REVOKE FILE - 执行后务必
FLUSH PRIVILEGES;,否则权限不生效
配置文件怎么写、怎么验证
不能用 SET GLOBAL secure_file_priv = NULL 动态设置——会报错 ERROR 1238 (HY000): Variable 'secure_file_priv' is a read only variable。只能改配置文件:
- 找到真实生效的配置文件:
mysqld --help --verbose | grep "Default options",或查SELECT @@global.config_file;(部分版本支持) - 在
[mysqld]段下添加:secure_file_priv = NULL - 保存后重启服务:
sudo systemctl restart mysql(Debian/Ubuntu)或sudo brew services restart mysql(macOS Homebrew) - 验证是否生效:
SELECT @@secure_file_priv;返回结果必须是NULL(不是字符串"NULL",也不是空值)
容易被忽略的兼容性细节
MySQL 5.7 不支持 secure_file_priv = NULL,设了会启动失败。如果你用的是 5.7,只能退而求其次:设为一个不存在的路径(如 /dev/null),并确保该路径不可写,再配合彻底撤回 FILE 权限。但这种组合不是原子禁用,仍有极小概率被利用。真正的禁用只在 8.0.17+ 可靠实现——别信文档里“设为空即禁用”的说法,那是旧版误导。











