mysql 5.7 中禁止给匿名用户(user='')授权,因其存在高危安全隐患,必须用 drop user ''@'host' 删除,不可 grant;定位需执行 select user,host from mysql.user where user='';删除后须验证返回空集,并通过 mysql_secure_installation 防再生。

MySQL 5.7 中不能也不该给匿名用户(user 为空字符串)设置权限——它本身就是安全隐患,必须删除,而不是授权。
为什么不能给 ''@'localhost' 授权
匿名用户是 user 字段为 '' 的记录,MySQL 在认证时会优先匹配空用户名(尤其当 host 匹配且无更精确用户时),导致任意未显式指定用户名的连接都可能命中它。这类账户通常无密码、无明确用途,且权限模型无法可靠约束其行为。官方文档和安全审计工具(如 mysql_secure_installation)默认将其列为高危项并强制清除。
试图执行类似 GRANT SELECT ON test.* TO ''@'localhost'; 会失败或产生不可预测结果:MySQL 5.7+ 不允许对空用户名使用 GRANT,报错 ERROR 1410 (42000): You are not allowed to create a user with GRANT 或直接忽略。
如何准确定位所有匿名用户记录
登录 MySQL(需有 SELECT ON mysql.* 权限),运行:
SELECT user, host, authentication_string FROM mysql.user WHERE user = '';
注意点:
-
user = ''是唯一可靠条件,IS NULL或LIKE ''无效 - 结果中
host可能为'localhost'、'%'或具体 IP,每条都需单独处理 - 不要依赖
SHOW GRANTS FOR ''@'localhost'—— 它常报错或返回空,因该用户本身不支持标准权限查询
删除匿名用户的正确方式(5.7+ 必须用 DROP USER)
对每条查出的记录,执行:
DROP USER ''@'localhost';
常见错误与应对:
-
ERROR 1396 (HY000): Operation DROP USER failed:说明该用户不存在或已损坏,跳过即可 - 误删后想恢复?不行。MySQL 不提供回滚
DROP USER,务必先备份mysql.user表(mysqldump mysql user > user_backup.sql) - 执行后必须验证:
SELECT user, host FROM mysql.user WHERE user = '';应返回空集 - 旧版兼容写法(如从 5.6 升级遗留):
DELETE FROM mysql.user WHERE user = '';+FLUSH PRIVILEGES;,但 5.7+ 强烈不推荐
删完还要防再生:关键配置漏掉就白干
匿名用户常在以下场景悄悄复活:
- 运行
mysql_secure_installation前手动执行过CREATE USER '@localhost';(用户名缺失) - 应用部署脚本硬编码了空用户名创建逻辑
- 使用低版本迁移工具未适配 5.7 的
authentication_string字段,导致插入空user
预防动作:
- 安装后第一件事就是跑
mysql_secure_installation,它会自动清理匿名用户、禁用远程 root、删 test 库 - 禁止普通账号写入
mysql.user表:REVOKE INSERT, DELETE, UPDATE ON mysql.user FROM 'app_user'@'%'; - 在 CI/CD 流程中加入检查脚本:
mysql -Nse "SELECT COUNT(*) FROM mysql.user WHERE user = ''",非 0 则阻断发布
真正棘手的不是怎么删,而是删完没人盯日志、没人卡流程、没人审计初始化脚本——空用户名会在你重启 mysqld 或导入旧 dump 时冷不丁冒出来。











