MySQL权限过大不是“功能强”,而是给攻击者递刀子。一旦账号被撞库、钓鱼或会话劫持,高权限账户能直接导出全库、删除核心表、读取服务器文件,甚至提权到操作系统层面。真实攻防演练中,70%以上的数据库横向渗透都始于一个
root@
'%'或误配的
app_user拥有
FILE和
SUPER权限。
查谁有越权能力:别只看 GRANT OPTION,重点盯 Super_priv 和 Repl_slave_priv
很多人以为只要没开
WITH GRANT OPTION就安全了,其实更危险的是那些能绕过权限检查的管理类权限:
SUPER权限允许 kill 任意连接、修改
sql_mode、绕过只读限制——等于数据库里的“root shell”
Repl_slave_priv常被忽略,但它能让攻击者伪装成从库,配合
LOAD DATA LOCAL INFILE读取服务器任意文件(如
/etc/shadow)
FILE权限不只用于导出,还能写入 Web 目录造成 GetShell,或覆盖配置文件
执行这条语句快速定位:
SELECT user, host, Super_priv, Repl_slave_priv, File_priv FROM mysql.user WHERE Super_priv='Y' OR Repl_slave_priv='Y' OR File_priv='Y';
业务账号为何不能用 % 通配 host?DNS 欺骗和防火墙失效时它就是后门
把
'app_user'@'%'当作“方便运维”的捷径,实际等于放弃网络层第一道防线: host 为
'%'时,即使绑定了内网 IP,只要 MySQL 配置了
bind-address = 0.0.0.0,且防火墙规则松动,就可能被公网直连 若使用域名(如
'admin'@'db.company.com'),DNS 解析被污染或缓存投毒后,攻击者可将流量引向自己控制的服务器 正确做法是限定 CIDR 范围,例如
'app_user'@'10.20.0.0/16',并确保该段 IP 真实属于可信内网
SHOW GRANTS 结果不准:权限叠加、角色继承、动态权限全都不显示
运行
SHOW GRANTS FOR 'dev'@'localhost'看到的只是显式授予的权限,但真实权限可能是三重叠加的结果: 角色继承:如果
dev被赋予了
analyst_role,而该角色又有
SELECT权限,
SHOW GRANTS不会体现 动态权限(MySQL 8.0.16+):如
BACKUP_ADMIN、
CLONE_ADMIN存在
mysql.role_edges和
mysql.default_roles表中,不在
mysql.user字段里 代理用户(PROXY):通过
CREATE USER 'u'@'h' PROXY 'p'@'h';授予的间接权限,完全不会出现在常规查询中
要查完整权限链,得组合执行:
SELECT * FROM mysql.role_edges WHERE FROM_HOST = 'dev';<br>SELECT * FROM mysql.default_roles WHERE HOST = 'dev';
真正难的不是设权限,而是持续验证“此刻这个账号到底能干什么”。一次上线改配置、一次外包交接、一次临时提权修 bug,都可能留下僵尸权限。定期跑脚本比等审计报告更管用,尤其当你的
mysql.user表里还躺着
''@'localhost'这种空用户名的时候。
