mysql_upgrade 不检查系统表权限漏洞;它仅升级系统表结构,不审计权限配置,真正检测需查询 information_schema.TABLE_PRIVILEGES 等表并比对 mysql.tables_priv 等底层权限表。

mysql_upgrade 会检查系统表权限漏洞吗
不会。mysql_upgrade 的核心任务是升级系统表结构(比如 mysql.user、mysql.db 等表的字段和索引),确保它们匹配当前 MySQL 版本的内部要求。它不扫描、不审计、不验证权限配置是否合理——哪怕 root@localhost 被删了,或者 mysql.sys 被设成所有用户可写,mysql_upgrade 都不会报错或提醒。
真正能查系统表权限问题的命令是什么
得直接查 information_schema.TABLE_PRIVILEGES 和 information_schema.COLUMN_PRIVILEGES,再结合 mysql.tables_priv、mysql.columns_priv 这类底层表比对。常见高危场景包括:
-
GRANT SELECT ON mysql.* TO 'app_user'@'%'—— 暴露用户密码哈希(mysql.user.authentication_string) -
GRANT INSERT ON mysql.tables_priv TO 'attacker'@'10.0.0.%'—— 可写权限等于可控权限分发 -
SELECT * FROM mysql.user WHERE user = ''返回空用户行 —— 匿名登录可能开启
推荐快速筛查语句:
SELECT host,user,select_priv,insert_priv,update_priv,delete_priv FROM mysql.user WHERE user != 'root' AND (select_priv='Y' OR insert_priv='Y') AND (host LIKE '%' OR host LIKE '%%');
为什么升级后反而更容易暴露权限问题
MySQL 5.7+ 默认启用 sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,且禁用旧式 GRANT ... IDENTIFIED BY 语法;8.0 彻底移除 mysql.plugin 表写权限默认开放。这些变更会让原本“凑合能用”的宽松权限配置,在升级后触发显式拒绝或报错,比如:
- 应用仍用
GRANT USAGE ON *.* TO 'old_app'@'%' IDENTIFIED BY 'xxx'→ 报错ERROR 1064 (42000) - 备份脚本直连
mysql库执行INSERT INTO user→ 被拒绝,因 8.0 要求用CREATE USER+GRANT -
mysqld --skip-grant-tables启动后未重置密码就重启 → 权限表未加载,所有用户无权访问mysql库
检查权限漏洞时最常漏掉的两个点
一是忽略 DEFINER 存储过程/函数的执行上下文权限。比如一个 DEFINER='root'@'localhost' 的函数被普通用户调用,实际是以 root 权限读写系统表——这不属于 GRANT 列表里的显式权限,但危害等同。
二是忘记 performance_schema 和 sys 库的访问控制。MySQL 5.7+ 默认关闭 performance_schema 表的用户级权限检查,但若手动开了 UPDATE 权限给非 DBA 用户,就能篡改监控数据甚至触发 UDF 加载。
这两个地方不体现在 SHOW GRANTS 输出里,也不在 mysql_upgrade 检查范围内,得单独查 INFORMATION_SCHEMA.ROUTINES 和 performance_schema.setup_actors。










