天天看点

【DB吐槽大会】第52期 - PG 函数内容不支持加密

背景

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、数据库未来产品迭代如何修复这个坑

  • 内核层支持: 普通用户只能查询自己定义的函数或存储过程内容.
  • 内核层支持: 函数内容加密功能, 用户只能查看加密后的内容, 提高安全性. 加密密钥由启动数据库的操作系统用户或者通过文件形式读取输入, 权限可以与数据库用户区别开来.