PostgreSQL - 只允许DB用户调用函数

时间:2013-04-07 20:03:53

标签: postgresql stored-procedures transactions sql-injection user-permissions

目前我正在为我的应用程序使用PostgreSQL。由于我试图将包含事务的每个SQL(即插入,更新,删除)放在一个函数中,我偶然发现了这个问题:

是否有可能只允许数据库用户调用函数和Select-Statements而他无法调用包含事务的SQL语句? “呼叫功能”是指任何功能。无论它是否包含交易。

我已经尝试创建一个只能调用函数和Select-Statements的用户。但是在调用包含事务的函数时,我总是会遇到错误。据我所知,如果他调用使用insert,update或delete语句的函数,dbuser需要写权限。

我错过了什么吗?这种情况真的不可能吗?安全方面,这将是非常好的,因为你几乎首先阻止了SQL注入。

1 个答案:

答案 0 :(得分:29)

SELECT没有“特权”。您所需要的只是EXECUTE功能的特权。相关功能可以与SECURITY DEFINER一起运行,以继承所有者的所有权限。要将可能的权限提升限制为最小的先验,请使守护程序角色拥有仅具有必要权限的相关功能 - 而不是超级用户!

配方

作为超级用户...

创建非超级用户角色myuser

CREATE ROLE myuser PASSWORD ...;

创建一个组角色mygroup并在其中加入myuser成员。

CREATE ROLE mygroup;
GRANT mygroup TO myuser;

您可能希望稍后添加更多用户,如myuser

不授予任何特权至myuser 只将这些内容授予mygroup

  • GRANT CONNECT ON DATABASE mydb TO mygroup;
  • GRANT USAGE ON SCHEMA public TO mygroup;
  • GRANT EXECUTE ON FUNCTION foo() TO mygroup;

删除public myuser不应拥有的REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public; 所有权限。

PUBLIC

可能还有更多。 I quote the manual:

  

PostgreSQL为某些类型的对象授予默认权限   CONNECT。默认情况下,表上没有为PUBLIC授予任何权限,   列,模式或表空间。对于其他类型,默认值   授予PUBLIC的权限如下:CREATE TEMP TABLEEXECUTE用于数据库; USAGE职能特权;和REVOKE   语言特权。当然,对象所有者可以REVOKE   默认和明确授予的权限。 (为了最大的安全性,问题   创建对象的同一事务中的ALTER DEFAULT PRIVILEGES;然后那里   没有其他用户可以使用该对象的窗口。)另外,这些   可以使用CREATE ROLE mydaemon; 命令更改初始默认权限设置。

拥有相关功能创建守护程序角色

mydaemon

仅授予执行这些函数所需的权限EXECUTE ON FUNCTION,(包括mydaemon以允许调用另一个函数)。同样,您可以使用组角色捆绑权限并将其授予GRANT bundle1 TO mydaemon;

ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES    TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE  ON SEQUENCES TO bundle1;

此外,您可以使用DEFAULT PRIVILEGES自动将未来对象的某些权限直接授予分发包或守护程序:

FOR ROLE

这仅适用于它执行的角色。 Per the documentation:

  

如果省略GRANT SELECT ON ALL TABLES IN SCHEMA public TO bundle1; GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO bundle1; ,则假定当前角色。

还要涵盖架构中的预先存在的对象(请参阅rob's comment):

mydaemon

CREATE OR REPLACE FUNCTION foo() ... SECURITY DEFINER SET search_path = myschema, pg_temp; ALTER FUNCTION foo() OWNER TO mydaemon; REVOKE EXECUTE ON FUNCTION foo() FROM public; GRANT EXECUTE ON FUNCTION foo() TO mydaemon; GRANT EXECUTE ON FUNCTION foo() TO mygroup; -- possibly others .. 拥有相关功能。可能看起来像这样:

REVOKE EXECUTE ON FUNCTION foo() FROM public;

<击> ###注
由于当前版本1.16.1中this bug pgAdmin所需的命令

{{1}}
逆向工程DDL脚本中缺少

。记得在重新创建时添加它。
此错误已在当前版本pgAdmin 1.18.1中修复。