应关闭local_infile、设secure_file_priv为null、开启skip_symbolic_links、启用strict_trans_tables;四者组合构成mysql文件操作与数据安全基线,缺一不可。

检查 local_infile 是否被意外启用
这个变量控制客户端能否通过 LOAD DATA LOCAL INFILE 读取服务器本地任意文件,一旦开启且应用存在 SQL 注入点,攻击者可直接读取 /etc/passwd、配置文件甚至私钥。
执行:SHOW VARIABLES LIKE 'local_infile'; —— 若返回 ON,即存在风险。
- 修复方式:在
my.cnf的[mysqld]段下添加local_infile = OFF,然后重启或执行SET GLOBAL local_infile = OFF;(注意:后者在某些版本中需 SUPER 权限且不持久) - 别信“我代码里没用这个语法”——只要变量开着,任何能拼接 SQL 的地方都可能被利用
- Docker 镜像或一键安装脚本常默认开启它,必须手动确认
验证 secure_file_priv 是否设为有效路径或 NULL
该变量限制 LOAD DATA INFILE 和 SELECT ... INTO OUTFILE 的读写目录。若为空字符串(''),表示不限制;若为 NULL,表示完全禁用这两类操作——这才是安全状态。
执行:SELECT @@secure_file_priv; —— 返回 NULL 是理想结果;返回空字符串或宽泛路径(如 /tmp)都是隐患。
-
/tmp不安全:多个服务共享,易被竞态写入恶意文件 - 设为具体路径(如
/var/lib/mysql-files/)也可接受,但必须确保该目录权限为750、属主为mysql:mysql - 修改后无需重启,但需确认 mysqld 进程对该路径有读写权限(常见坑:目录存在但属主是 root)
排查 skip_symbolic_links 是否关闭
关闭此选项允许 MySQL 跟随符号链接访问数据文件,攻击者可借此绕过 datadir 限制,读取或覆盖系统任意位置的文件(如覆盖 /etc/shadow 的硬链接)。
执行:SHOW VARIABLES LIKE 'skip_symbolic_links'; —— 返回 OFF 即危险;应为 ON(默认值)。
- 旧版配置或手动优化时可能被误关,尤其在调优 InnoDB 文件布局时
- 即使你没主动建 symlink,也要防备攻击者通过其他漏洞创建
- 检查
my.cnf中是否显式写了skip_symbolic_links = 0或skip_symbolic_links = OFF
确认 sql_mode 是否包含 STRICT_TRANS_TABLES 或 STRICT_ALL_TABLES
非严格模式会让 MySQL 宽容处理非法数据(如超长字符串截断、零日期插入),不仅导致业务逻辑错乱,更可能掩盖注入尝试或权限绕过行为(例如构造特殊字符串触发未预期的隐式转换)。
执行:SELECT @@sql_mode; —— 检查输出中是否含 STRICT_TRANS_TABLES(推荐)或 STRICT_ALL_TABLES。
- 缺失 strict 模式时,
INSERT INTO users VALUES ('admin', 'xxx' + ' OR 1=1')可能静默失败而非报错,让 WAF 或日志漏掉异常模式 - 生产环境建议设为
STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,避免因引擎不支持而静默降级 - 注意:修改后需测试应用兼容性,部分老系统依赖宽松截断行为
这些变量不是“开了就安全,关了就危险”的开关,而是组合生效的安全基线。最容易被忽略的是 secure_file_priv 返回 NULL 和 local_infile 关闭这两项——它们构成文件操作的第一道闸门,一旦失守,后续所有权限控制都形同虚设。











