令人惊讶的行为角色权限

来自 PostgreSQL 维基
跳转到导航跳转到搜索

简介

这*不是*关于安全漏洞。这里的所有问题都是已知的,并且在大多数情况下至少间接地记录在案。

这份文档是关于那些不直观且很难正确记录的行为,因此可能会给用户一种错误的安全感。

意外

用户无法控制使用其权限执行的代码。

对普通对象(如表和视图)的普通访问(例如 INSERT、SELECT)可以执行任意代码,并且没有实际的方法可以阻止这种情况,甚至不知道将执行什么代码。由对象所有者编写的代码将使用访问该对象的用户的权限执行。

唯一安全的做法是只访问您*绝对*信任的用户拥有的对象,例如超级用户或您角色的成员。如果对象所有者不是显式地您角色的成员,而您访问该对象,那么他们实际上就像您角色的成员一样。

实际上,这意味着我们的权限系统是分层的,但没有记录为这种方式。对象所有者使用 GRANT 分配细粒度的权限,访问这些对象的必须完全信任对象所有者。

函数作者不知道他们的函数会做什么。

PL/pgSQL 函数或使用 SPI 的任何函数都依赖于search_path来查找甚至是最基本的函数和运算符,例如>。因此,调用者可以轻松地操纵搜索路径,以便函数或运算符解析为另一个模式中相同名称的函数/运算符,该模式由调用者创建,并包含任意代码。

这会产生两个潜在问题

1. 对于SECURITY DEFINER函数,最明显的问题是作者必须绝对控制函数的行为,因为它使用作者的权限执行。

2. 一个更微妙的问题是,当对象所有者依赖函数返回正确的结果时,例如在约束定义中。调用者可以操纵函数的行为,使其返回错误的结果并错误地通过约束检查,从而违反约束。

这些问题可以通过在函数定义中指定SET search_path子句来解决。为了安全起见,任何可能被另一个用户直接或间接调用的函数都应该声明一个SET search_path子句,但重要性没有被充分记录。此外,该行为是默认不安全的(函数具有公共 EXECUTE 权限,没有SET search_path),并且一般来说,这种做法不被鼓励或广泛使用。

没有办法删除权限。

删除权限最直观的方法,SET SESSION AUTHORIZATIONSET ROLE,都可以在同一个会话中撤消。

技巧和特殊情况。

在某些情况下,权限更高的用户需要访问权限较低的用户拥有的对象。例如,表维护(例如 REINDEX)和逻辑复制。PostgreSQL 并没有普遍解决用户无法控制使用其权限执行什么代码的问题,而是简单地为维护命令开辟了特殊情况。这意味着超级用户对非特权用户拥有的表执行 REINDEX 是安全的,但在同一个表上执行 INSERT 或 SELECT 则非常危险。