背景
1、产品的问题点
- PG 函数内容不支持加密
2、问题点背后涉及的技术原理
- PG 可以写函数支持较为复杂的业务逻辑, 或者讲逻辑写入函数从而减少客户端与数据库的交互.
- 但是PG的函数内容不支持加密功能. 任何用户都可
postgres=# \du
List of roles
Role name | Attributes | Member of
-----------+------------------------------------------------------------+---------------------
abc | Cannot login | {}
d | Cannot login | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
ro | | {pg_read_all_data}
rw | | {pg_write_all_data}
postgres=# alter role abc login;
ALTER ROLE
postgres=# create or replace function hello(int) returns void as $$
postgres$# declare
postgres$# begin
postgres$# perform 1 from pg_class;
postgres$# perform $1+$1;
postgres$# end;
postgres$# $$ language plpgsql strict;
CREATE FUNCTION
postgres=# select hello(1);
hello
-------
(1 row)
postgres=# \c postgres abc
You are now connected to database "postgres" as user "abc".
postgres=> select * from pg_proc where proname='hello';
-[ RECORD 1 ]---+---------------------------
oid | 376507
proname | hello
pronamespace | 354435
proowner | 10
prolang | 14228
procost | 100
prorows | 0
provariadic | 0
prosupport | -
prokind | f
prosecdef | f
proleakproof | f
proisstrict | t
proretset | f
provolatile | v
proparallel | u
pronargs | 1
pronargdefaults | 0
prorettype | 2278
proargtypes | 23
proallargtypes |
proargmodes |
proargnames |
proargdefaults |
protrftypes |
prosrc | +
| declare +
| begin +
| perform 1 from pg_class;+
| perform $1+$1; +
| end; +
|
probin |
prosqlbody |
proconfig |
proacl |
3、这个问题将影响哪些行业以及业务场景
- 通用
4、会导致什么问题?
- 存在一定的安全风险, 任何用户都可以查询数据库中其他用户定义的函数内容
5、业务上应该如何避免这个坑
- 回收pg_proc系统表权限.
revoke select on pg_proc from public;
- 回收pg_catalog.pg_get_functiondef函数权限.
revoke execute on function pg_catalog.pg_get_functiondef from public;
6、业务上避免这个坑牺牲了什么, 会引入什么新的问题
- 导致所有的函数定义都无法查询, 包括自己定义的.
7、数据库未来产品迭代如何修复这个坑
- 内核层支持: 普通用户只能查询自己定义的函数或存储过程内容.
- 内核层支持: 函数内容加密功能, 用户只能查看加密后的内容, 提高安全性. 加密密钥由启动数据库的操作系统用户或者通过文件形式读取输入, 权限可以与数据库用户区别开来.