PostgreSQL RLS 显式策略

PostgreSQL RLS explicit Policies

从安全的角度来看,以下策略的实施是否等效?

隐式:

CREATE POLICY test_access_policy ON test 
  TO PUBLIC 
  USING (id = (current_setting('rls.id'::TEXT))) 
  WITH CHECK (TRUE);

显式:

CREATE POLICY test_insert_policy ON test 
  FOR INSERT TO PUBLIC
  WITH CHECK (TRUE);   

CREATE POLICY test_select_policy ON test
  FOR SELECT TO PUBLIC 
  USING (id = (current_setting('rls.id'::TEXT)));  

CREATE POLICY test_update_policy ON test 
  FOR UPDATE TO PUBLIC
  USING (id = (current_setting('rls.id'::TEXT)));   

CREATE POLICY test_delete_policy ON test 
  FOR DELETE TO PUBLIC 
USING (id = (current_setting('rls.id'::TEXT)));

我担心的是更新政策,如 docs 中所述:

Any rows whose updated values do not pass the WITH CHECK expression will cause an error, and the entire command will be aborted. If only a USING clause is specified, then that clause will be used for both USING and WITH CHECK cases.

根据我的理解,隐式版本(oneliner)的等效更新策略如下:

CREATE POLICY test_update_policy ON test 
  FOR UPDATE TO PUBLIC 
  USING (id = (current_setting('rls.id'::TEXT))) WITH CHECK (TRUE);

而显式版本是:

CREATE POLICY test_update_policy ON test 
  FOR UPDATE TO PUBLIC 
  USING (id = (current_setting('rls.id'::TEXT))) WITH CHECK (id =
(current_setting('rls.id'::TEXT)));

在测试这两种情况后,我没有找到任何安全桥,我是否遗漏了什么?

您的解释是正确的,您必须将 WITH CHECK (TRUE) 添加到 FOR UPDATE 政策才能获得等效定义。

不同之处在于 WITH CHECK (TRUE) 允许您将值更改为任何值,如果没有它,如果新行版本与条件不匹配,您将收到错误消息。