ON . 授权会绕过库级隔离,因它赋予全局权限且mysql.db中Db='%'记录允许模糊匹配访问任意库,甚至可查mysql.user等系统表;验证需查mysql.db和mysql.user表;防护须禁用通配符授权、禁用GRANT OPTION、关闭show_database_privilege及远程root。

为什么 ON *.* 授权会直接绕过库级隔离
MySQL 的 GRANT 语句里写 ON *.*,等于把全局权限(包括对所有系统库的访问能力)一次性全开。这不是“授权太宽”,而是彻底放弃隔离边界——哪怕你后续再 REVOKE 某个库,只要 mysql.db 表里还存着 Db = '%' 的记录,用户就能通过模糊匹配访问任意库。更危险的是,GRANT SELECT ON *.* 还会让用户能 SELECT 系统表(如 mysql.user),而 MySQL 并不阻止这种操作。
如何验证当前有没有用户被误授了 *.* 权限
直接查权限元数据表最可靠,别信 SHOW GRANTS 的美化输出:
SELECT User, Host, Db FROM mysql.db WHERE Db = '%';
如果有结果,说明至少有一个用户拥有全库通配权限;再补查:
SELECT User, Host FROM mysql.user WHERE Select_priv = 'Y' OR Insert_priv = 'Y' OR Update_priv = 'Y';
如果返回行中包含 Host 是 '%' 且没被显式限制库名,基本可判定存在风险账号。注意:8.0+ 中 mysql.user 表的权限字段只反映全局权限,库级权限仍以 mysql.db 为准。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
禁止通配符授权的实操底线
真正起效的防护不是靠事后审计,而是从建号流程卡死入口:
- 新建用户后,**第一句必须是
GRANT USAGE ON *.*** —— 它不给任何操作权,只允许连接,是安全占位符 - 后续授权严格限定格式:
GRANT SELECT ON app_db.users TO 'app_user'@'10.20.30.%',库名和表名一个都不能省、不能用*替代 - 禁用
GRANT OPTION,否则用户自己就能扩散权限:WITH GRANT OPTION必须从所有GRANT语句里删干净 - 定期跑脚本清理冗余账号:
DROP USER IF EXISTS 'old_user'@'%';,避免'user'@'%'和'user'@'10.20.30.%'同时存在导致权限叠加
生产环境必须关掉的两个默认行为
MySQL 默认允许某些宽松行为,不手动关掉,权限策略形同虚设:
-
show_database_privilege变量在 8.0.29+ 才可用,但默认是OFF;要真正隐藏非授权库名,得先SET GLOBAL show_database_privilege = ON;,再确保用户没被授予SHOW DATABASES权限 - 删除
root账号的远程访问能力:DROP USER IF EXISTS 'root'@'%';,只保留'root'@'localhost'或绑定内网段如'root'@'192.168.1.%'
最容易被忽略的一点:权限变更后,FLUSH PRIVILEGES 并非总是必要——只有直接修改 mysql. 系统表时才需要它;但如果你用的是配置文件加载或代理层同步机制,漏掉这步就等于没改。

















