空密码账户等于敞开大门,须立即识别处理;查 authentication_string 为空、单星号或 null 的账号,需用 trim() 防空格伪装,并注意匿名用户 ''@'localhost'。

空密码账户在 MySQL 中等于敞开大门,只要能连上就能直接登录。这类账号往往不是人为创建,而是初始化遗留、脚本误操作或旧版本升级残留,必须第一时间识别并处理。
查 authentication_string 为空或占位符的账号
MySQL 5.7+ 完全依赖 authentication_string 字段判断密码状态,Password 字段已废弃。空字符串 ''、单星号 '*' 或该字段为 NULL 都代表无密码。
- 执行
SELECT host, user, plugin, authentication_string FROM mysql.user WHERE LENGTH(TRIM(authentication_string)) = 0 OR authentication_string IN ('', '*'); -
TRIM()必须加——攻击者可能用空格填充伪装成非空值 - 结果中若出现
user为空(即''@'localhost')也要一并标记,这是典型的匿名空密码入口 - 注意:该查询需以具备
SELECT ON mysql.*权限的账号(如root)执行,普通账号看不到mysql.user
区分插件类型再筛短哈希(防误判弱密)
不是所有短哈希都等于弱口令,得先看认证插件。不同插件下合法哈希长度不同:mysql_native_password 是 41 位,caching_sha2_password 是 72 位 Base64。长度明显偏离,才可能是原始密码极短(如 '1'、'test')。
- 只对
plugin = 'mysql_native_password'的用户查短哈希:SELECT host, user, authentication_string FROM mysql.user WHERE plugin = 'mysql_native_password' AND LENGTH(authentication_string) -
caching_sha2_password用户不能用长度法初筛,得靠预计算哈希比对(如明文'123456'对应固定 Base64 值) - 若看到
authentication_string是'*1'或'*0'这种 2~3 位值,基本可断定原始密码就是单字符,直接归为高危
别跳过 CURRENT_USER() 和 SHOW GRANTS 验证
查出空密码账号后,不能直接删。有些看似“空用户”的账号,其实是你当前正在使用的登录身份,删了会导致自己被锁死。
- 先执行
SELECT USER(), CURRENT_USER();:前者是你声明的登录名,后者是 MySQL 实际匹配到的账号(即生效的user@host)。如果CURRENT_USER()返回''@'localhost',说明你正通过空密码账号登录 - 对每个可疑账号运行
SHOW GRANTS FOR ''@'localhost';(必须带完整@'host'),确认它是否只有USAGE权限,还是已经绑定了ALL PRIVILEGES - 若
SHOW GRANTS返回空或仅USAGE,仍不能掉以轻心——得继续查mysql.role_edges,防止它通过角色继承获得高权限
真正危险的不是“有没有空密码”,而是“有没有一个空密码账号同时拥有高权限且监听公网”。很多团队扫出 ''@'localhost' 就删,却漏掉了 'admin'@'%' 虽有密码但强度为 0,或者 'root'@'192.168.1.%' 的密码已被爆破——这些都得在同一轮审计里覆盖。











