必须同时撤销SYSTEM_VARIABLES_ADMIN、SESSION_VARIABLES_ADMIN、CONNECTION_ADMIN和SUPER权限,并执行FLUSH PRIVILEGES;仅撤其一或未刷新缓存,SET GLOBAL或SET PERSIST仍可成功,因权限拆分、角色继承或高危权限残留导致绕过。

必须同时撤销 SYSTEM_VARIABLES_ADMIN、SESSION_VARIABLES_ADMIN、CONNECTION_ADMIN 和 SUPER 四类权限,并执行 FLUSH PRIVILEGES;只撤一个或漏掉 FLUSH PRIVILEGES,SET GLOBAL 或 SET PERSIST 仍能成功。
为什么只 REVOKE SYSTEM_VARIABLES_ADMIN 不够
MySQL 8.0+ 中,变量修改能力被拆散到多个独立权限里,它们互不替代、可单独存在:
-
CONNECTION_ADMIN隐式允许SET GLOBAL,且优先级高于SYSTEM_VARIABLES_ADMIN撤销结果 -
SESSION_VARIABLES_ADMIN支持SET PERSIST,会写入mysqld-auto.cnf,重启后自动加载为全局值 -
SUPER虽标记为 deprecated,但未显式回收就依然有效——旧账号常残留此权限 - 用户可能通过角色(如
mysql.session)间接继承上述任一权限,SHOW GRANTS不显示角色内嵌权限
怎么查清用户真实拥有的变量权限
别信记忆或 SHOW GRANTS 输出,权限是叠加生效的,必须交叉查系统表:
- 查角色授予的变量权限:
SELECT * FROM information_schema.role_table_grants WHERE grantee = "'user'@'host'" AND privilege_type IN ('SYSTEM_VARIABLES_ADMIN', 'SESSION_VARIABLES_ADMIN', 'CONNECTION_ADMIN'); - 查直接授权:
SHOW GRANTS FOR 'user'@'host';,确认输出里没有这四类权限 - 查是否属于高危内置角色:
SELECT * FROM mysql.role_edges WHERE TO_HOST = 'host' AND TO_USER = 'user'; - 验证是否拦截成功:
SELECT @@global.max_connections;应返回Access denied; you need (at least one of) the SYSTEM_VARIABLES_ADMIN privilege(s)
精准回收权限的完整操作清单
顺序不能错,缺一不可:
- 一次性撤销核心权限:
REVOKE SYSTEM_VARIABLES_ADMIN, SESSION_VARIABLES_ADMIN, CONNECTION_ADMIN, SUPER ON *.* FROM 'user'@'host'; - 显式清理
SUPER(即使提示 deprecated):REVOKE SUPER ON *.* FROM 'user'@'host'; - 强制刷新缓存:
FLUSH PRIVILEGES;—— 动态权限撤销后不执行这句等于没撤 - 特别注意 host 匹配:如果应用连的是
'app'@'10.20.30.40',而你只撤了'app'@'%',权限依然生效
最容易被忽略的是权限匹配粒度——MySQL 控制的是「连接时使用的凭据」,不是登录后的身份切换;另外,SET PERSIST 写入的配置文件路径(mysqld-auto.cnf)若未被清理,重启后可能恢复旧值,需同步检查该文件内容。


















