plperl 是postgresql支持的函数语言之一。
在使用plperl时,可以使用plperl提供的钩子功能,满足一些特殊场景的需求。
钩子分2种,一种是加载plperl.so库时的钩子,一种是加载perl语言解释器时的钩子。
钩子的使用有安全问题吗?
相关参数
plperl.on_init (string)
当设置了 shared_preload_libraries = 'plperl' 预加载时,plperl.on_init 只会被调用一次。
当没有设置 shared_preload_libraries = 'plperl' 预加载时,plperl.on_init 会在每个会话第一次装载plperl.so时被调用。
代码
src/pl/plperl/plperl.c
plperl.on_init (string) 只能设置在配置文件中,或者在启动postgres时命令行指定。
对只开放普通数据库用户的环境来说没有安全问题。
plperl 函数语言钩子,当在会话中第一次加载perl语言解释器时,perl 函数解释器将自动调用
或设置的串。
具体调用哪个,和函数语言有关,plperl则调用on_plperl_init, plperlu则调用on_plperlu_init。
需要注意的是,这两个函数可以在参数中设置,也能在会话中设置,但是在会话中设置的话,如果perl解释器已经加载了,不会触发修改后的值。
另外需要注意on_plperl_init是在plperl安全化后执行的,所以即使在这里配置了不安全的属性,也不怕,因为会直接报错。(与调研plperl的用户权限无关,plperl是不允许执行不安全操作的,例如调研system接口)
这两个参数的解释 :
<a href="https://www.postgresql.org/docs/9.5/static/plperl-under-the-hood.html">https://www.postgresql.org/docs/9.5/static/plperl-under-the-hood.html</a>
plperl.on_plperl_init (string)
plperl.on_plperlu_init (string)
代码如下
只有超级用户能设置这两个值,普通用户在会话中设置plperl.on_plperl_init时,触发设置则报错。
postgresql.conf 参数
测试
使用 stat touch /home/digoal/t123 查看时间戳的变化
判断是否触发。
plperl是trust语言,在创建它的函数时,会监测安全性,例如过滤一些os操作,等。普通用户和超级用户都可以创建plperl语言的函数。
plperlu则是untruste语言,允许任何操作,只有超级用户能创建plperlu的函数。
如果已经设置了plperl.on_plperl_init是一个不安全的值,则新建plperl函数会报错。
调用时,如果触发了不安全的plperl.on_plperl_init,也会报错。
postgresql将函数语言分为两类,一类是trust的另一类是untrust的。
trust的语言,不允许执行有破坏性的操作,例如系统命令,文件访问等。普通用户可以创建trust语言的函数。
untrust的语言,允许执行任何操作,只有superuser能创建untrust语言的函数。
如果只开放普通数据库用户出去,是没有安全风险的。
postgresql 为 plperl或plperlu语言设置了两种钩子,分别允许在加载libperl.so时被触发(在_pg_init(void)里面实现);
或者在加载perl解释器时被触发,其中加载解释器时又分为两种,plperl和perlu的设置。
用户利用钩子,可以实现一些特殊场景的应用。
数据库普通用户无法修改钩子参数
即使设置了危险的plperl.on_plperl_init参数,因为这个参数的内容是在plperl函数风险评估后执行的,所以如果有风险也不允许执行,不存在安全风险。
综上,postgresql对语言的管理是非常安全的,只要不随意把超级用户放出去,不随意使用untrust语言创建不安全的函数。