file权限是服务器文件系统操作权,非单纯导出权限,可读写任意本地路径;secure_file_priv为唯一限制机制,但需重启生效,空字符串''或null须立即处理,应用账号应禁用该权限。

FILE权限不是“导出权限”,而是服务器文件系统操作权
很多人看到SELECT INTO OUTFILE或LOAD DATA INFILE就以为FILE权限只是配合数据导出导入用的,其实它直接让MySQL服务进程(通常是mysql用户)以自身身份读写服务器本地任意可访问路径。这意味着:
- 攻击者执行
SELECT LOAD_FILE('/etc/passwd')就能读取系统账号信息 - 执行
SELECT ... INTO OUTFILE '/var/www/html/backdoor.php'可向Web目录写入恶意脚本 - 配合
LOAD DATA INFILE加载/usr/lib/mysql/plugin/udf.so可提权执行系统命令
这些操作完全不依赖用户是否登录操作系统,纯SQL即可触发。
secure_file_priv配置极易失效,且无法动态调整
secure_file_priv是唯一能限制FILE权限作用范围的机制,但它有硬伤:
- 启动时加载,运行中
SET GLOBAL secure_file_priv = ...会报错,必须改my.cnf并重启mysqld - 若值为
NULL,FILE权限被禁用;若为空字符串'',等于完全放开——很多旧环境默认就是'' - 即使设为
/var/lib/mysql-files/,也得确保该目录仅mysql用户可写、其他用户不可读,否则仍是高危点
检查当前配置只需一条:SELECT @@secure_file_priv;,返回''或NULL必须立刻处理。
应用账号几乎从不需要FILE权限,授了反而暴露漏洞链
绝大多数业务场景里,应用根本不会调用LOAD DATA INFILE或SELECT INTO OUTFILE:
- 常规SQL导入(
mysql -u user db_name )走的是网络协议,不涉及服务端文件I/O,不需要FILE权限 - 云数据库(如阿里云RDS、腾讯云CDB)默认禁用FILE权限,且
GRANT FILE会直接报错ERROR 1227 (42000) - 如果代码里真用了
INTO OUTFILE,说明逻辑设计有问题——应该改应用,而不是开权限
一旦应用账号被撞库或注入,FILE权限就成了提权链上最关键的跳板。
替代方案更安全、更可控
真有导入导出需求,应绕过FILE权限,用更稳妥的方式:
- ETL任务用
mysqldump --single-transaction+ 客户端文件传输,不依赖服务端写文件 - 需要加载外部数据时,先用
scp或sftp把文件放到secure_file_priv指定目录,再由DBA账号执行LOAD DATA INFILE - 严格回收:执行
REVOKE FILE ON *.* FROM 'app_user'@'%';,再查SELECT User,Host,File_priv FROM mysql.user WHERE File_priv='Y';确认清空
FILE权限在生产环境中没有“低风险用法”——只要开了,风险就在那里,不取决于你用没用。











