PostgreSQL的函数安全定义解说

上周,由DBA+杭州群联合发起人周正中分享的PostgreSQL使用安全指导性文章,让大家在数据库的加固操作上受益匪浅。而本周,他将分享关于PostgreSQL的函数安全定义解说。

 

专家简介

  

周正中

网名:德哥@Digoal

DBA+杭州群联合发起人之一

 

PostgreSQL中国社区发起人之一,负责杭州分会,兼任社区CTO一职。曾就职于斯凯网络,负责数据库部门。现就职于阿里巴巴,负责RDS PG内核组事务。

 

 
 

PostgreSQL函数可以设置被调用时的角色,以及参数。详细的语法如下:

 

 

当函数被调用时,可以选择以创建函数的角色执行函数,或者以调用者的角色执行函数(默认)。

 

同时,我们还可以设置函数被调用时的参数。

 

我们可以跟踪一下,跟踪角色需要用到session_user和current_user,这两者的差别可参考如下代码:

 

src/backend/utils/init/miscinit.c

 

session_user是指登陆数据库时的角色或者被SET SESSION AUTHORIZATION设置的角色。

 

current_user是指set role设置的角色,或者继承自session user,或者是函数调用时定义的角色。

 

举个例子,先搞明白这两个用户的含义:

 

 

创建测试函数:

 

 

这里的security definer表示调用函数时,使用函数owner的权限进行调用。

 

set search_path to 'public',表示在调用函数时,使用这个值作为search_path。

 

 

使用digoal用户连接到postgres数据库,并调用postgres.f1()函数:

 

 

从NOTICE可以看到我们对函数的设置起作用了。search_path是我们设置的public,而不是默认的 "$user",public。

 

current_role则是函数的definer postgres。

 

 

因此我们使用security definer时,需特别注意,因为可能造成权限升级,例如本文使用超级用户创建的security definer函数。

 

我们把这个函数的security改为invoker。再次使用digoal调用f1(),可以看到current_role是digoal了。

 

 

下面举个例子,说明security definer的不安因素。使用超级用户创建一个函数如下,用于检查用户是否通过密码认证。

 

 

但是如果设置为security definer,想想有什么安全隐患呢?

 

 

这样看貌似没有隐患,但是因为函数中没有使用schema.table的方式,所以我们可以使用普通用户自己建立一张认证表,并自定义search_path来修改扫描优先级,来通过认证,甚至可以使用临时表的SCHEMA,都不需要修改search_path(因为临时表schema优先级被排在最前),偷偷就搞定了。

 

 

为了提高security definer函数的安全性。可以有以下方法。

 

1. 建议在里面使用的函数或表等一切对象,都使用schema强制指定。

 

2. 设置search_path, 防止普通用户钻空子。

 

例如:

 

 

现在钻不了空子了:

 

 

或者在调用函数时使用设置的search_path,将普通用户能创建表的schema都去除。

 

 

现在也安全了:

 

 

不过这里还是推荐在函数中使用schema,防止这类问题。

 

 

 

时间: 2024-08-28 13:52:45

PostgreSQL的函数安全定义解说的相关文章

c语言数组与函数-如何在函数中给已经在主函数中定义好的数组赋值

问题描述 如何在函数中给已经在主函数中定义好的数组赋值 已经在main()中定义了一个长度为20的数组,想在定义的函数中给数组赋值,但一直报错,请问如何修改? void arrin(int *arr) { int i; arr[]={1,1,2,2,3,3,4,5,6,5,6,7,7,8,8,9,9,0,0}; for(i=0;i<20;i++) printf("%d",arr[i]); } main() { int testarr[20]; ............ } 解决方

qmap-QT Qmap 在一个函数中定义,怎么在另一个函数中遍历

问题描述 QT Qmap 在一个函数中定义,怎么在另一个函数中遍历 50C void address_pool::set_address_pool(QString get_IP){ QString ip; ip= get_IP; qDebug()<<""IP""<<ip; QStringList str=ip.split(""); QStringList strlist= str.at(0).split("&qu

Flash AS学习:函数的定义和调用

函数 演示效果: 点击这里下载源文件 有人将函数比喻成一个加工的机器,一个碾米机输入的是稻谷,输出的是大米:一个random(5)函数,输入的是5,输出的是0~4的任意一个:random()是FLASH本身内置的,我们可以自己定义一个这样的加工的机器,这样,输入什么,输出什么,就全由我们自己作主了.现在开始定义一个这样的函数,只要我们输入一个数,就输出这个数的3倍的数. function cont(n:Number){ trace(3*n) } 以上定义了一个函数,这个函数好比一个停放在这里没有

C++中内联函数的定义和使用

引入内联函数的目的是为了解决程序中函数调用的效率问题. 函数是一种更高级的抽象.它的引入使得编程者只关心函数的功能和使用方 法,而不必关心函数功能的具体实现:函数的引入可以减少程序的目标代码,实 现程序代码和数据的共享.但是,函数调用也会带来降低效率的问题,因为调用 函数实际上将程序执行顺序转移到函数所存放在内存中某个地址,将函数的程序 内容执行完后,再返回到转去执行该函数前的地方.这种转移操作要求在转去前 要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执 行.因此,函数调

运行word宏出现“子过程或函数未定义”怎么办

  故障分析:一般这种情况是跟宏里面的VBA编辑器有关系,或者是用户版本几用户安装了新的工具箱所导致工具宏无法运行,出现出现"子过程或函数未定义"的故障. 解决方法: 一.如果你制作了worddot模板的话,应该是你的dot模板被修改了,找到normal.dot文件删除掉应该就可以了.或者尝试进入[C:UsersSolomanAppDataRoamingMicrosoftWordSTARTUP]这个文件夹中,删掉里边的文件即可.再来重新运行word应用程序查看是否有异常. 二.如果你在

jQuery回调函数的定义及用法实例_jquery

本文实例讲述了jQuery回调函数的定义及用法.分享给大家供大家参考.具体分析如下: jQuery代码中对回调函数有着广泛的应用,对其有精准的理解是非常有必要的,下面就通过实例对此方法进行简单的介绍. 代码实例如下: 利用回调函数,当div全部隐藏之后弹出一个提示框. 复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset=" utf-8"> <meta name="a

从字符串到分数的构造器,在构造器函数的定义处调试时有“写入位置访问冲突”问题

问题描述 从字符串到分数的构造器,在构造器函数的定义处调试时有"写入位置访问冲突"问题 #define _CRT_SECURE_NO_WARNINGS #include #include using namespace std; class Fraction { private: int num, den; public: Fraction(char s[10]); void set(int n, int d){ num = n; den = d;normalize(); } int

c-在函数里面定义的 int a(); 这是什么意思?

问题描述 在函数里面定义的 int a(); 这是什么意思? void main(){ int a();} 这样也可以编译通过.这是什么意思呢? 解决方案 int a()是声明的int型的函数,需要返回0,一般声明void型,不用返回值 解决方案二: 这是 定义一个 函数名为a 返回值为 int 的函数 解决方案三: 主函数内的函数定义,该函数只在主函数中可用. 解决方案四: 我第一反应以为是进行无参构造函数呢...晕

2013级C++第11周项目——函数的定义与调用

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759 [项目1-调用函数输出星号图] 这一组的练习意在通过调用函数输出星号图,体会与理解函数的工作过程,并为其后编制自定义函数实现特定功能. (1)补充完下面的程序,使程序输出星号图: #include <iostream> using namespace std; void printstars(int m) //定义能输出一行m个星号的函数 { for (int j=1;