Postgresql:noInherit 不起作用?

Postgresql : noInherit not working?

所以,我想弄清楚如何正确管理 postgresql 数据库。 我是 postgres 和 DBA 的新手。

我目前正在尝试为特定数据库担任专门角色。 我还想让其他用户获得该角色的授权,这样我就可以 SET ROLE my_db_role 并能够从那里操作这个特定的数据库。 但是,我有权限泄漏,这意味着我可以在不执行此 SET ROLE my_db_role 命令的情况下操作我的数据库。

以下是我为获得不成功的结果而执行的命令:

=# CREATE ROLE test NOINHERIT;
=# CREATE USER myuser;
=# CREATE DATABASE test OWNER test;
=# \c test
=# DROP SCHEMA public;
=# CREATE SCHEMA AUTHORIZATION test;
=# GRANT test TO myuser;
=# \c test myuser
=> CREATE TABLE test.mytable(id integer);
CREATE TABLE
Temps : 46,469 ms

为什么最后的命令成功了?

在我看来,myuser 应该没有测试 database/schema 的权限,因为测试角色有 NOINHERIT 标志,所以这个 CREATE 命令应该是不可能的。 它应该需要做 SET ROLE test 才能成功,但这里不是这种情况。

我错过了什么?

附带说明一下,除了官方文档之外,我很难找到有关如何正确管理 postgresql 的良好信息来源。如果你能分享一些好的material,非常欢迎你。

恐怕我不知道有任何关于角色管理和管理的特别好的资源。这里的标准显示出必须取悦多个利益相关者的所有迹象,并且灵活但令人困惑。

至于你的直接问题,问题是 "NOINHERIT" 的角色不对。但是,此功能并不是真正的安全限制。

test=# ALTER USER myuser NOINHERIT;
test=# \c - myuser
You are now connected to database "test" as user "myuser".
test=> CREATE TABLE test.mytable(id int);
ERROR:  permission denied for schema test
LINE 1: CREATE TABLE test.mytable(id int);
                     ^
test=> SET ROLE test;
SET
test=> CREATE TABLE test.mytable(id int);
CREATE TABLE

如您所见,myuser 不继承 test 的权限,但没有什么可以阻止您直接切换到该角色。

如果您觉得这很繁琐且令人困惑,那么您并不孤单。我发现添加一些 tests 来检查我设置的任何配置很有用。

因为test是数据库的所有者,它基本上对它的后续对象拥有所有权限。

正如@Richard Huxton 所指出的那样,在 test 角色上设置 NOINHERIT 会阻止它继承其他角色,但不会阻止它的特权被继承给其他角色。

当你发出:

GRANT test TO myuser;

您只需将与所有者相同的权限授予myuser,因此myuser可以创建对象,实际上它可以做任何所有者可以做的事情。

这不是 PostgreSQL 的问题,而是所有权的工作方式。不管怎样,你可以明确地撤销所有者的权限(例如,不要错误地破坏一个重要的对象)。

但是您应该考虑角色 myuser 的其他权限策略,使其不从所有者那里继承,而是只授予它需要的东西。如果用户可以创建一个table,它应该被祝福:

GRANT CREATE ON SCHEMA test TO myuser;

我知道您对 PostgreSQL 权限管理有点失望,一开始它似乎很难通过文档理解。为了更好地了解它的实际工作原理,您应该发出:

REVOKE ALL ON DATABASE test FROM public; 

然后所有角色都需要 CONNECTSCHEMA USAGE 的显式特权。然后您将发现对象和权限之间的依赖关系。多看GRANT页,再简洁也应该够了。

关于 SET ROLE 安全性 "issue",它仅限于当前角色所属的所有角色:

The specified role_name must be a role that the current session user is a member of. (If the session user is a superuser, any role can be selected.)

因此,用户无法覆盖其特权,它只能认可已授予它的其他身份。