确认匿名用户和test库是否残留:先执行select user, host from mysql.user where user = '' or user in ('test', 'test')和show databases like 'test';若任一返回结果,即存在安全隐患,须按版本执行drop user/delete from mysql.db等清理并强制flush privileges。

怎么确认匿名用户和 test 库还活着
别信 mysql_secure_installation 一路回车就完事了。它默认只删 ''@'localhost',但漏掉 ''@'127.0.0.1'、''@'::1' 和 'test'@'%' 是常态。
先连进 MySQL(用有 SUPER 权限的账号),执行这两条:
SELECT User, Host FROM mysql.user WHERE User = '' OR User IN ('test', 'TEST');
SHOW DATABASES LIKE 'test';
只要第一句返回任意 User 为空或为 test 的行,第二句返回 test,就说明隐患还在。
MySQL 5.7+ 必须三步一起删,缺一不可
DROP USER 只删账号,不碰权限表;FLUSH PRIVILEGES 不自动清缓存;DROP DATABASE 和权限清理是独立动作。漏一步,攻击者就能靠 CREATE DATABASE test 或 USE test 写入恶意数据。
- 删账号:
DROP USER IF EXISTS ''@'localhost'; DROP USER IF EXISTS ''@'127.0.0.1'; DROP USER IF EXISTS ''@'::1'; DROP USER IF EXISTS 'test'@'localhost'; DROP USER IF EXISTS 'test'@'%'; - 清残留权限:
DELETE FROM mysql.db WHERE User IN ('', 'test'); DELETE FROM mysql.tables_priv WHERE User IN ('', 'test'); - 强制重载:
FLUSH PRIVILEGES;(Docker / systemd 下尤其不能省)
MySQL 5.6 及更早版本只能走底层删表
DROP USER ''@'localhost' 在 5.6 会直接报错 ERROR 1396 (HY000),因为老版本没实现该语法的完整校验逻辑。
必须用:
DELETE FROM mysql.user WHERE User = '' AND Host IN ('localhost', '127.0.0.1', '::1');
再补上:
DELETE FROM mysql.db WHERE User = '';
最后 FLUSH PRIVILEGES; —— 这步不是可选,是必须。否则内存里还缓着空用户匹配规则,照样能连。
删完 test 库后还要检查 mysql.db 里有没有 test 相关的 wildcard 条目
很多人删了 test 数据库,却忘了 mysql.db 表里可能还存着 Db = 'test' 或 Db = 'test\_%' 的旧授权记录。这些条目不会随 DROP DATABASE 自动清除,下次有人创建同名库,权限立刻复活。
查一遍:
SELECT Host, Db, User FROM mysql.db WHERE Db LIKE 'test%';
如果结果非空,手动删掉:
DELETE FROM mysql.db WHERE Db LIKE 'test%'; FLUSH PRIVILEGES;
真正容易被跳过的,是 mysql.db 和 mysql.tables_priv 这两张表里的残留。它们不显眼,也不在用户列表里,但攻击链一旦触发,就是最高权限入口。











