直接查mysql.user表是合规检查第一步,重点核查User/Host是否存在及匹配、Super_priv/Grant_priv/File_priv高危组合、root非localhost配置及弱密码风险。

直接查 mysql.user 表看用户是否存在且 host 匹配
权限问题八成卡在第一步:用户根本没建对,或者 Host 字段不匹配。MySQL 把 'app'@'localhost' 和 'app'@'127.0.0.1' 当作两个完全不同的账号——前者走 Unix socket,后者走 TCP 连接,哪怕在同一台机器上也会登录失败。
执行 SELECT User, Host FROM mysql.user;,重点核对三件事:
- 目标用户是否真实存在(注意大小写和单引号)
- 应用连接方式对应的
Host值是否存在(远程连就该有'%'或具体 IP;本地命令行连localhost才合理) - 有没有干扰项,比如
''@'localhost'(匿名用户),它会优先匹配,导致预期用户权限不生效
用 mysql.user 的 _priv 字段快速识别高危权限组合
mysql.user 表里的所有 _priv 字段(如 Super_priv、Grant_priv、File_priv)都是 enum('N','Y') 类型,直接反映全局权限基线。别只看“有没有权限”,要看“谁在不该有权限的地方有权限”。
必须跑这条语句:SELECT User, Host, Super_priv, Grant_priv, File_priv FROM mysql.user WHERE Super_priv = 'Y' OR Grant_priv = 'Y' OR File_priv = 'Y';
- 特别警惕
Host = '%'且任意一项为'Y'的结果:远程可连 + 高权限 = 最高风险组合 -
User = 'root' AND Host != 'localhost'是等保明确禁止的配置,必须清理 -
CHAR_LENGTH(authentication_string)比authentication_string = ''更可靠,能捕获 MySQL 5.7 哈希截断导致的弱密码
注意 mysql.user 不是权限全貌,但它是权限校验第一关
MySQL 权限校验第一步就是从 mysql.user 中匹配一条记录,匹配依据只有 Host 和 User 两个字段——它们构成联合主键。这意味着哪怕只改一个字符(比如 'localhost' 和 '127.0.0.1'),就代表完全不同的用户条目。
常见错误现象:
- 执行
CREATE USER 'app'@'%'后仍无法远程连接,但本地能连:很可能mysql.user里同时存在'app'@'localhost'和'app'@'%',而客户端实际走的是前者(例如用127.0.0.1连却误匹配到localhost条目) -
SHOW GRANTS FOR 'u'@'h'返回空或报错,不是权限没生效,而是这个账号在mysql.user里根本不存在 - 直接
UPDATE mysql.user或插入mysql.tables_priv记录来“快速”调权,会导致权限行为异常——因为绕过了 MySQL 的权限校验逻辑,且SHOW GRANTS不显示它们
别用 SHOW GRANTS 替代直查 mysql.user 表
SHOW GRANTS 看起来权威,但它只展示显式授予的语句,会漏掉三类关键风险:
- 角色(Role)继承的权限:用户被赋予角色
R,R有DROP权限,但SHOW GRANTS只显示GRANT ROLE R,不展开R的实际内容 - 库/表级细粒度授权:
mysql.db或mysql.tables_priv里存在Insert_priv = 'Y',但不会出现在SHOW GRANTS输出中 - 动态权限(MySQL 8.0+):
BACKUP_ADMIN、CLONE_ADMIN等不存于mysql.user,得查performance_schema.role_edges或information_schema.role_table_grants
所以,合规检查第一步不是看日志,也不是跑 SHOW GRANTS,而是直查 mysql.user 表——它暴露了所有账号的全局权限基线。


















