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

lef*_*thy 18 postgresql stored-procedures sql-injection transactions user-permissions

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

是否有可能只允许数据库用户调用函数和选择语句,而他无法调用包含事务的SQL语句?"呼叫功能"是指任何功能.无论它是否包含交易.

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

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

Erw*_*ter 32

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

食谱

作为超级用户......

创建非超级用户角色myuser.

CREATE ROLE myuser PASSWORD ...;
Run Code Online (Sandbox Code Playgroud)

创建组角色mygroupmyuser在其中创建成员.

CREATE ROLE mygroup;
GRANT mygroup TO myuser;
Run Code Online (Sandbox Code Playgroud)

您可能希望像myuser以后一样添加更多用户.

不要完全不授予任何权限myuser.
只授予这些mygroup:

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

删除所有权限publicmyuser不应该有.

REVOKE ALL ON ALL TABLES IN SCHEMA myschema FROM public;
Run Code Online (Sandbox Code Playgroud)

可能会有更多.我引用手册:

PostgreSQL为某些类型的对象授予默认权限 PUBLIC.默认情况下,对表,列,模式或表空间不授予PUBLIC权限.对于其他类型,是授予PUBLIC的默认权限如下:CONNECTCREATE TEMP TABLE为数据库; EXECUTE职能特权; 和USAGE 语言特权.当然,对象所有者既可以REVOKE默认也可以明确授予权限.(为了最大限度地提高安全性,请REVOKE在创建对象的同一事务中发出;然后没有其他用户可以使用该对象的窗口.)此外,可以使用该ALTER DEFAULT PRIVILEGES命令更改这些初始默认权限设置.

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

CREATE ROLE mydaemon;
Run Code Online (Sandbox Code Playgroud)

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

GRANT bundle1 TO mydaemon;
Run Code Online (Sandbox Code Playgroud)

此外,您还可以使用DEFAULT PRIVILEGES以直接向bundle或daemon自动授予将来对象的某些特权:

ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES    TO bundle1;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT USAGE  ON SEQUENCES TO bundle1;
Run Code Online (Sandbox Code Playgroud)

这仅适用于它执行的角色.根据文件:

如果FOR ROLE省略,则假定当前角色.

还要覆盖架构中的预先存在的对象(请参阅rob的注释):

GRANT SELECT ON ALL TABLES    IN SCHEMA public TO bundle1;
GRANT USAGE  ON ALL SEQUENCES IN SCHEMA public TO bundle1;
Run Code Online (Sandbox Code Playgroud)

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 ..
Run Code Online (Sandbox Code Playgroud)

###注意
由于pgAdmin当前版本1.16.1中的这个错误是必要的命令

REVOKE EXECUTE ON FUNCTION foo() FROM public;
Run Code Online (Sandbox Code Playgroud)

在逆向工程DDL脚本中缺少.记得在重新创建时添加它.
此错误已在当前版本pgAdmin 1.18.1中修复.