背景
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、資料庫未來産品疊代如何修複這個坑
- 核心層支援: 普通使用者隻能查詢自己定義的函數或存儲過程内容.
- 核心層支援: 函數内容加密功能, 使用者隻能檢視加密後的内容, 提高安全性. 加密密鑰由啟動資料庫的作業系統使用者或者通過檔案形式讀取輸入, 權限可以與資料庫使用者差別開來.