目前我正在为我的应用程序使用PostgreSQL。由于我试图将包含事务的每个SQL(即插入,更新,删除)放在一个函数中,我偶然发现了这个问题:
是否有可能只允许数据库用户调用函数和Select-Statements而他无法调用包含事务的SQL语句? “呼叫功能”是指任何功能。无论它是否包含交易。
我已经尝试创建一个只能调用函数和Select-Statements的用户。但是在调用包含事务的函数时,我总是会遇到错误。据我所知,如果他调用使用insert,update或delete语句的函数,dbuser需要写权限。
我错过了什么吗?这种情况真的不可能吗?安全方面,这将是非常好的,因为你几乎首先阻止了SQL注入。
答案 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 TABLE
和EXECUTE
用于数据库;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中修复。