应执行select user, host from mysql.user;检查''@'localhost'、''@'::1'、'test'@'localhost'等匿名及测试账号,并用show databases;和select db from mysql.db where db like 'test%';确认test库及权限残留,再按规范清理。

怎么确认当前有哪些匿名账户和测试数据库
连上 MySQL 后,先执行 SELECT User, Host FROM mysql.user;,重点看有没有 ''@'localhost'、''@'::1'、'test'@'localhost' 这类条目;再执行 SHOW DATABASES; 看是否存在 test 数据库。注意:MySQL 5.7 默认可能不创建 test 库,但权限表里仍可能残留相关记录(比如 mysql.db 表中 Db='test' 的行)。
删除匿名用户必须用 DROP USER,不能只删权限
匿名用户是空用户名(''),不是密码为空——它根本不需要认证就能登录,风险极高。执行以下语句清理:
DROP USER IF EXISTS ''@'localhost';DROP USER IF EXISTS ''@'::1';DROP USER IF EXISTS ''@'%';
别用 DELETE FROM mysql.user WHERE User='';,这只会删记录,不会同步清理权限表(如 mysql.db、mysql.tables_priv),残留权限可能被复用。另外,DROP USER 在 5.7 中会自动清理所有授权表,但不会动数据库本身。
test 数据库要分两步删:库 + 权限残留
即使 SHOW DATABASES; 没看到 test,也得查权限表:SELECT Db, User, Host FROM mysql.db WHERE Db LIKE 'test%';。如果有结果,说明它虽无库体,但仍有访问入口。操作顺序如下:
- 删库:
DROP DATABASE IF EXISTS test; - 删权限残留:
DELETE FROM mysql.db WHERE Db = 'test' OR Db = 'test\_%';(注意反斜杠要转义) - 刷新权限:
FLUSH PRIVILEGES;
漏掉第二步的话,攻击者仍可通过 USE test; 触发权限检查绕过,尤其在某些老客户端或协议解析异常时。
执行后务必验证是否真清干净
删完别直接退出,立刻验证:
- 再跑一遍
SELECT User, Host FROM mysql.user;,确认无空用户名 - 执行
SELECT User, Host FROM mysql.user WHERE User = 'test';,应无返回 - 查权限残留:
SELECT Db FROM mysql.db WHERE Db = 'test';,也应为空 - 尝试用空用户连接:
mysql -u '' -h localhost -e "SELECT USER();",应报错拒绝访问
最容易被忽略的是 mysql.db 表里的通配符残留(如 test_xxx),它不会出现在 SHOW DATABASES 里,却能被 GRANT ... ON `test_xxx`.* 引用——这种“幽灵权限”在等保测评中常被扣分。











