查super_priv='y'是覆盖5.7及之前版本的唯一方式,mysql 8.0+需联查mysql.role_edges补角色路径,show grants不显示super且不可信,须实操kill或set global验证。

SUPER 权限就是最典型的“过大管理员权限”,查它最直接也最容易漏人
查 mysql.user 表里的 Super_priv = 'Y'
这是所有 MySQL 版本都必须做的第一步,也是唯一能覆盖 5.7 及之前全部情况的方式。字段值是快照,不走视图、不依赖角色,查到就是真有。
-
Super_priv大小写敏感:必须写成Super_priv,super_priv或SUPER_PRIV会报错或返回空 - 执行账号需有
SELECT ON mysql.*权限,普通用户默认没有,得用root或带SYSTEM_USER角色的账号 - 刚执行过
GRANT SUPER ON *.* TO 'u'@'h'但没FLUSH PRIVILEGES,表里可能还是'N',而权限已生效——此时SHOW GRANTS才是真实依据 - 系统账户如
mysql.session、mysql.infoschema也显示Super_priv = 'Y',但它们不能登录,不算 DBA 可用的“真实”超级账号
MySQL 8.0+ 必须联查 mysql.role_edges 补角色路径
8.0 引入角色后,Super_priv = 'Y' 不再代表全部。用户可以没直连 'Y',却通过角色间接获得 SUPER。只查 mysql.user 会漏掉这类账号。
- 先查谁绑了角色:
SELECT FROM_USER, FROM_HOST, TO_ROLE FROM mysql.role_edges; - 对每个
TO_ROLE,执行SHOW GRANTS FOR 'role_name'@'%';—— 注意角色名必须带主机名,否则失败 - 若输出含
GRANT SUPER ON *.* TO,说明该角色链能提供SUPER;再反查哪些用户被授了这个角色:SELECT User, Host FROM mysql.user u JOIN mysql.role_edges r ON u.User = r.FROM_USER AND u.Host = r.FROM_HOST WHERE r.TO_ROLE = 'xxx'; - 用户必须已执行
SET ROLE 'xxx';才能激活角色权限;否则即使查到角色链,实际也无SUPER
别信 SHOW GRANTS 输出里有没有 SUPER
SHOW GRANTS FOR 'u'@'h' 输出里永远不会出现 SUPER 关键字,哪怕用户真有该权限。这是 MySQL 内部设计限制,不是你查错了。
- 它只展示显式
GRANT语句,不解析角色继承、不读取mysql.user字段 - 常见错觉:执行
SHOW GRANTS没看到GRANT SUPER ON *.*,就以为没权限 —— 实际可能是通过角色继承,或早期用INSERT INTO mysql.user手动改过字段 - 验证是否真能用:可以试执行
KILL 123或SET GLOBAL max_connections = 1000;,比看语句更直接
真正难的不是查出谁有 SUPER,而是确认“谁正在用它”。权限字段是静态快照,角色需手动激活,升级残留配置可能让旧角色继续生效 —— 这些细节一漏,审计就等于白做。











