information_schema是MySQL内置只读视图集合,按权限过滤暴露元数据:普通用户仅可见其有权限的库、表、字段;mysql库真实字典表受服务层硬拦截,不可直接访问。

普通用户查 INFORMATION_SCHEMA 不是“绕过权限”,而是设计如此
MySQL 的 INFORMATION_SCHEMA 本质是一组只读视图,不是真实的数据字典表。它对外暴露元数据时,**默认就做了权限过滤**:你只能看到自己有权限访问的库、表、字段等对象。所以普通用户能查 INFORMATION_SCHEMA.TABLES 并不奇怪——它返回的只是“你被允许知道的那部分”,比如你有 SELECT 权限的表,或者你被显式授权过的库里的表。这不是漏洞,是 MySQL 元数据访问层的正常行为。
mysql 库下的真实字典表,普通用户根本查不了
MySQL 8.0 把核心数据字典迁移到了 mysql 库的内部 InnoDB 表(如 mysql.tables、mysql.columns),但这些表在发行版中受严格保护:
- 直接
SELECT * FROM mysql.tables会报错:ERROR 3554 (HY000): Access to data dictionary table 'mysql.tables' is rejected - 即使你有
SELECT权限,也无法绕过这个限制;这是服务层硬编码的拦截,不走常规权限检查流程 - 只有调试版本或特定内部账号(如
mysql.sys)才可能访问,生产环境不可能开放
真正要警惕的是 SHOW DATABASES 和 INFORMATION_SCHEMA.SCHEMATA 的可见性差异
这两个看似都能列出数据库,但行为不同:
-
SHOW DATABASES只显示你有任意权限(哪怕只是USAGE)的库;没权限的库完全不出现 -
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA默认会列出所有库名(包括你没权限的),除非启用了show_compatibility_56=OFF且 MySQL 8.0+ 配置了information_schema_stats_expiry=0等特殊条件 - 所以如果你发现普通用户能“看到不该看的库名”,问题往往出在
INFORMATION_SCHEMA.SCHEMATA的默认行为,而不是权限被绕过
别误把 SELECT 权限当成“全量元数据访问权”
很多同学以为只要给了 SELECT,就能通过 INFORMATION_SCHEMA 探出整个库结构——其实不然:
- 查
INFORMATION_SCHEMA.COLUMNS时,只返回你有权限访问的字段(比如被COLUMNS_PRIV显式屏蔽的列不会出现) - 查
INFORMATION_SCHEMA.STATISTICS时,若没有INDEX权限,某些索引信息可能为空或被省略 - 表注释(
TABLE_COMMENT)和字段注释(COLUMN_COMMENT)始终可见——这是唯一不被权限过滤的元数据项,也是最容易被忽略的信息泄露点
最常被忽略的是:权限过滤发生在元数据解析阶段,不是执行阶段。这意味着,连 SHOW CREATE TABLE 这种语句,如果用户对某张表没有任何权限,MySQL 根本不会去查它的定义,而是直接报 ERROR 1142 或更早的 ERROR 1146。所以“能查到”和“能查全”之间,差的不是权限开关,而是整个元数据可见性模型的设计逻辑。


















