暂无图片
暂无图片
5
暂无图片
暂无图片
暂无图片

困扰 MySQL 用户多年的问题,它只用一个插件就解决了!

原创 Lucifer三思而后行 2025-11-19
449

目录

前言

上周有个朋友问我:“哥,我们刚从 MySQL 8.0 迁到金仓数据库的 MySQL 兼容模式,发现一个很神奇的 BUG”!

当我在金仓数据库中新建了一个用户以及表,没有对这个用户授权该表的访问权限,但是可以在 sys_class 表中查询到这个表的信息。

也就是说,即使用户没有表的访问权限,也能从系统表(sys_class)查询到该表的存在和元数据信息,这是金仓数据库的 BUG 还是 MySQL 原来就存在这种问题呢?

其实,这既不是金仓的 BUG,也不是 MySQL 的 BUG,而是一个长期存在的数据库安全设计问题。 值得一提的是,金仓数据库在近期将会发布一个新的功能插件 security_utils,针对这个问题进行修复,避免元数据的泄露问题,也是对 MySQL 兼容模式的安全增强!

我这里也是申请到了内测版的安装包,本文将演示一下如何使用 security_utils 插件进行用户的权限隔离,避免元数据泄露!

MySQL 数据库

MySQL 数据库确实存在元数据泄露的问题:

-- 即使用户没有权限,也能查询到表的存在 mysql> SELECT table_name FROM information_schema.tables WHERE table_schema = 'mydb'; +------------+ | table_name | +------------+ | orders | | customers | | salaries | -- 工资表,敏感! +------------+

这是 MySQL 的默认设计,不是 BUG,但确实是安全隐患。从 MySQL 5.x 版本到 MySQL 8.0+ 版本都有相关的改进:

版本 行为
MySQL 5.x 所有用户可查看所有数据库的表结构
MySQL 8.0+ 引入部分隔离,但仍可探测表存在性

但注意:即使 MySQL 8.0,默认仍可通过 SHOW TABLESinformation_schema 查看未授权表的名称。

金仓数据库

正如开头的朋友所说,金仓数据库也是存在这种设计问题,下面我用一个例子进行还原。

首先,创建一个表以及用户:

kingbase=# CREATE TABLE orders ( order_id INT PRIMARY KEY, customer_id INT, amount DECIMAL(10,2), order_date DATE); kingbase=# INSERT INTO orders VALUES (1, 1001, 5999.00, '2024-11-01'), (2, 1002, 3299.00, '2024-11-15'); kingbase=# CREATE USER finance with password 'Finance@123';

切换到 finance 用户查询:

kingbase=# \c - finance 用户 finance 的口令: 您现在以用户名"finance"连接到数据库"kingbase"。 kingbase=> select oid,relname from sys_class where relname='orders'; oid | relname -------+--------- 16644 | orders kingbase=> select * from orders; ERROR: permission denied for table orders kingbase=> \dt 关联列表 架构模式 | 名称 | 类型 | 拥有者 ----------+--------+--------+-------- public | orders | 数据表 | system kingbase=> \d orders 数据表 "public.orders" 栏位 | 类型 | 校对规则 | 可空的 | 预设 -------------+---------------+----------+----------+------ order_id | integer | | not null | customer_id | integer | | | amount | numeric(10,2) | | | order_date | date | | | 索引: "orders_pkey" PRIMARY KEY, btree (order_id NULLS FIRST)

可以发现,此时 finance 用户并没有表 orders 的访问权限,但是仍然可以通过 sys_class 查看到 orders 表的元数据,甚至是表结构,这是十分不安全。

加载插件

金仓数据库提供用户权限隔离功能,用户权限隔离功能开启后,普通用户只能查看有权访问的对象(表、函数、视图、字段等)。

用户权限隔离功能开启需要加载插件 security_utils,在使用 security_utils 之前,我们需要将他添加到 kingbase.conf 文件的 shared_preload_libraries 中,并重启 KingbaseES 数据库:

shared_preload_libraries = 'security_utils'

重启数据库生效:

[kingbase@kesv9:/install]$ sys_ctl restart -D /data/ 等待服务器进程关闭 .... 完成 服务器进程已经关闭 等待服务器进程启动 ....2025-08-27 00:08:29.862 CST [93180] LOG: config the real archive_command string as soon as possible to archive WAL files 2025-08-27 00:08:29.869 CST [93180] LOG: sepapower extension initialized 2025-08-27 00:08:29.903 CST [93180] LOG: starting KingbaseES V009R003C012 2025-08-27 00:08:29.903 CST [93180] LOG: listening on IPv4 address "0.0.0.0", port 54321 2025-08-27 00:08:29.903 CST [93180] LOG: listening on IPv6 address "::", port 54321 2025-08-27 00:08:29.905 CST [93180] LOG: listening on Unix socket "/tmp/.s.KINGBASE.54321" 2025-08-27 00:08:29.986 CST [93180] LOG: redirecting log output to logging collector process 2025-08-27 00:08:29.986 CST [93180] HINT: Future log output will appear in directory "sys_log". 完成 服务器进程已经启动

开启权限隔离功能:

kingbase=# \c - system 您现在以用户名"system"连接到数据库"kingbase"。 -- 开启功能 kingbase=# create extension kdb_schedule; CREATE EXTENSION kingbase=# create extension security_utils; CREATE EXTENSION

至此,用户隔离的插件已开启。

实战演示

接下来,演示一下 Kingbase MySQL 兼容模式如何进行用户权限隔离。

数据库级别开启用户权限隔离:

kingbase=> \c - system 用户 system 的口令: 您现在以用户名"system"连接到数据库"kingbase"。 kingbase=# alter database kingbase enable object isolation; ALTER DATABASE

再切换到 finance 用户查询:

kingbase=# \c - finance 用户 finance 的口令: 您现在以用户名"finance"连接到数据库"kingbase"。 kingbase=> select oid,relname from sys_class where relname='orders'; oid | relname -----+--------- (0 行记录) kingbase=> \dt Did not find any relations. kingbase=> \d orders Did not find any relation named "orders".

已经无法查询到 sys_class 中 orders 表的信息,包括元数据以及表结构,都已经无法查看。

如果想要访问以上元数据,则需要人为进行授权该表给用户才行:

kingbase=> \c - system 用户 system 的口令: 您现在以用户名"system"连接到数据库"kingbase"。 kingbase=# grant select on table orders to finance; GRANT

再切换到 finance 用户查询:

kingbase=# \c - finance 用户 finance 的口令: 您现在以用户名"finance"连接到数据库"kingbase"。 kingbase=> select oid,relname from sys_class where relname='orders'; oid | relname -------+--------- 16644 | orders (1 行记录) kingbase=> \dt 关联列表 架构模式 | 名称 | 类型 | 拥有者 ----------+--------+--------+-------- public | orders | 数据表 | system (1 行记录) kingbase=> \d orders 数据表 "public.orders" 栏位 | 类型 | 校对规则 | 可空的 | 预设 -------------+---------------+----------+----------+------ order_id | integer | | not null | customer_id | integer | | | amount | numeric(10,2) | | | order_date | date | | | 索引: "orders_pkey" PRIMARY KEY, btree (order_id NULLS FIRST)

可以发现,金仓数据库通过插件方式实现了开关式的一键开关用户权限隔离功能,十分方便快捷。

金仓数据库的这个功能,技术底层实现依赖 行级安全策略(Row-Level Security, RLS),通过修改数据库状态,为当前数据库具有 ACL 字段的系统表统一添加配置好的 RLS,通过 RLS 筛选以实现普通用户只能查看有权访问的对象(表、函数、视图、字段等)的目的。

写在最后

在数字化时代,数据安全至关重要,数据库权限管理是核心保障。金仓数据库通过 security_utils 插件提供了超越 MySQL 原生能力的安全特性,补齐了 Oracle 级别的安全特性,通过插件化实现,兼顾灵活性和安全性。

同时,金仓数据库高度兼容 MySQL 的语法与基本功能,降低应用迁移成本,还在权限管理上实现功能增强,能满足金融、医疗等领域复杂需求,为企业数字化转型提供可靠数据安全支撑。

最后修改时间:2025-11-20 09:39:22
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论