RLS依赖的列更新时,Postgres RLS更新条件不满足

问题描述 投票:0回答:1

我有一个 Postgres 数据库,其中有一个表

profile
。该表有两列:
id
username
。我已启用 RLS 并应用了以下策略。

 schemaname | tablename |         policyname          | permissive |  roles   |  cmd   |                            qual                            | with_check 
------------+-----------+-----------------------------+------------+----------+--------+------------------------------------------------------------+------------
 public     | profile   | select_user_or_group_policy | PERMISSIVE | {public} | SELECT | (current_setting('myapp.username'::text, true) = username) | 
 public     | profile   | unrestricted_insert         | PERMISSIVE | {public} | INSERT |                                                            | true
 public     | profile   | unrestricted_update         | PERMISSIVE | {public} | UPDATE | true                                                       | true
 public     | profile   | unrestricted_delete         | PERMISSIVE | {public} | DELETE | true                                                       | 

myapp.username
由外部应用程序设置,但出于测试目的,通过调用

设置

select set_config('myapp.username', 'user1', false);
.

从数据库中选择数据时,我发现它按预期工作,仅返回用户名与

myapp.username
配置匹配的行。更新时,我希望策略允许我更新我在更新开始时可以看到的任何记录。我希望能够将
username
更改为其他用户,但这样做时出现以下错误。我很困惑,因为更新策略设置为
USING (true) WITH CHECK (true)

更新前的表(表的 id 列有主键,其他列没有限制。

id 用户名
1 用户1
2 用户2
UPDATE profile SET username = 'user2' WHERE id = 1;
ERROR:  new row violates row-level security policy for table "profile"
postgresql rls
1个回答
0
投票

问题是

SELECT
策略也用于检查新行,因此您无法执行使行看起来消失的更新。

参见源码中的注释(

get_row_security_policies()
中的函数
src/backend/rewrite/rowsecurity.c
):

/*
 * Get and add ALL/SELECT policies, if SELECT rights are required for
 * this relation (eg: when RETURNING is used).  These are added as WCO
 * policies rather than security quals to ensure that an error is
 * raised if a policy is violated; otherwise, we might end up silently
 * dropping rows to be added.
 */
© www.soinside.com 2019 - 2024. All rights reserved.