关于PostgreSQL 15新特性的文章,已经写过如下几篇文章:
<<PG 15devel Merge Into语法测试>>
<<PostgreSQL 15新特性预览:版本兼容性>>
<<PostgreSQL 15新特性预览:json日志>>
还有一篇部分新特性实验的文档:
<<PostgreSQL 15新特性预览>>
本文将介绍视图的security invoker选项有什么实际的作用。
一、函数的security context
首先我们从函数的security context,也就安全上下文环境说起。当我们编写完自己的函数,PostgreSQL在函数的执行上给我们提供的安全环境有两种:第一种是security invoker,以调用者权限执行函数,这是默认的安全环境。另一种环境是security definer,以创建者权限执行函数,创建者权限在函数执行期间生效。
security invoker方式普通用户定义的函数体如果包含高危操作时,虽然自己没有权限执行,但如果被高权限的管理用户执行会触发函数陷阱。而security definer则可以把明确的高权限操作以创建者权限给用户提高权限。
二、视图默认的security context
一直以来,视图使用security definer,也就是说PostgreSQL是使用视图的owner去检测相关对象的权限。而函数的执行并不是以security definer方式。
下面我们进行视图的测试:
postgres=# create user test;
CREATE ROLE
postgres=# create table tab_base as select 1 as id;
SELECT 1
postgres=# create view my_view as select * from tab_base;
CREATE VIEW
postgres=# grant select on my_view to test;
GRANT
postgres=# \c - test
postgres=> select * from my_view;
id
----
1
(1 row)
上面我们创建基表tab_base,然后创建视图my_view,接着我们只需把视图的部分权限,只需把视图的select赋予给test用户,test用户就可以访问到数据。
这也是使用视图非常方便的特性,可以减少视图里相关对象的权限设置而允许用户有部分访问权限,但我们仍然需要注意security_barrier视图属性对视图攻击的安全保护,这一点官方文档也有详细的示例说明,视图使用security_barrier属性示例如下:
CREATE VIEW xxx WITH (security_barrier) AS
SELECT xxx FROM xxx ...;
三、视图security invoker使用场景
我们继续上面的测试来观察视图新增的security_invoker属性有什么作用。
postgres=# alter view my_view set (security_invoker = on);
ALTER VIEW
postgres=# \c - test
You are now connected to database "postgres" as user "test".
postgres=> select * from my_view ;
ERROR: permission denied for table tab_base
当我们给视图增加security_invoker属性之后,系统将检查用户对视图相关对象(示例中的tab_base表)是否有权限,而不是只检查视图的owner权限。由于我们没有对tab_base表赋予权限给test用户,所以上面最后的查询语句提示无权限。
视图security_invoker的使用场景是当我们不想以视图owner进行权限检测,类似函数的security invoker方式(调用者权限方式)。
另外如果视图引用的对象如果有开启表的行级安全特性,如果是以owner方式进行检测,则行级安全策略会被跳过。因此security_invoker视图能与行级安全特性使用更加贴切。
四、视图security invoker总结
- 视图使用默认的security_invoker=off策略可以减少相关权限的设置而允许用户有部分访问权限,但需要注意视图安全攻击的影响。
- 视图使用security_invoker=on对行级安全策略能更加有效的同时使用,对函数的security context也更加融合。
保持联系
从2019年12月开始写第一篇文章,分享的初心一直在坚持,本人现在组建了一个PG乐知乐享交流群,欢迎关注我文章的小伙伴加我微信进群吹牛唠嗑,交流技术。