Re: row_security GUC, BYPASSRLS

From: Noah Misch <noah(at)leadboat(dot)com>
To: Stephen Frost <sfrost(at)snowman(dot)net>
Cc: Robert Haas <robertmhaas(at)gmail(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>, Joe Conway <mail(at)joeconway(dot)com>
Subject: Re: row_security GUC, BYPASSRLS
Date: 2015-09-21 05:45:10
Message-ID: 20150921054510.GA3786167@tornado.leadboat.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Sep 14, 2015 at 03:29:16AM -0400, Noah Misch wrote:
> On a related topic, check_enable_rls() has two kinds of RLS bypass semantics.
> Under row_security=off|on, superusers bypass every policy, and table owners
> bypass policies of their own tables. Under row_security=off only, roles with
> BYPASSRLS privilege additionally bypass every policy; BYPASSRLS doesn't affect
> semantics under row_security=on. Is that distinction a good thing? Making
> BYPASSRLS GUC-independent, like superuser bypass, would simplify things for
> the user and would make row_security no longer a behavior-changing GUC.
> row_security would come to mean simply "if a policy would otherwise attach to
> one of my queries, raise an error instead." Again, if you have cause to
> toggle BYPASSRLS, use multiple roles. Implementing that with GUCs creates
> harder problems.

Having pondered this further in the course of finalizing commit 537bd17,
arming BYPASSRLS independent of the row_security GUC is indeed a good thing.
Right now, if a BYPASSRLS user creates a SECURITY DEFINER function, any caller
can change that function's behavior by toggling the GUC. Users won't test
accordingly; better to have just one success-case behavior.

On Wed, Jul 29, 2015 at 09:09:27AM -0400, Stephen Frost wrote:
> For superuser (the only similar precedent that we have, I believe), we
> go based on the view owner, but that isn't quite the same as BYPASSRLS.
>
> The reason this doesn't hold is that you have to use a combination of
> BYPASSRLS and row_security=off to actually bypass RLS, unlike the
> superuser role attribute which is just always "on" if you've got it. If
> having BYPASSRLS simply always meant "don't do any RLS" then we could
> use the superuser precedent to use what the view owner has, but at least
> for my part, I'm a lot happier with BYPASSRLS and row_security than with
> superuser and would rather we continue in that direction, where the user
> has the choice of if they want their role attribute to be in effect or
> not.

If I make BYPASSRLS GUC-independent, I should then also make it take effect
when the BYPASSRLS role owns a view. Barring objections, I will change both.

I do share your wish for an ability to suppress privileges temporarily. I
have no specific design in mind, but privilege activation and suppression
should be subject to the approval of roles affected. GUCs probably can't
serve here; apart from the grandfathered search_path, functions can ignore
them. GUCs are mostly a property of the whole session.

By the way, is there a reason for RI_Initial_Check() to hard-code the rules
for RLS enablement instead of calling check_enable_rls(..., InvalidOid, true)
twice? I refer to this code:

> /*
> * Also punt if RLS is enabled on either table unless this role has the
> * bypassrls right or is the table owner of the table(s) involved which
> * have RLS enabled.
> */
> if (!has_bypassrls_privilege(GetUserId()) &&
> ((pk_rel->rd_rel->relrowsecurity &&
> !pg_class_ownercheck(pkrte->relid, GetUserId())) ||
> (fk_rel->rd_rel->relrowsecurity &&
> !pg_class_ownercheck(fkrte->relid, GetUserId()))))
> return false;

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Xiong He 2015-09-21 07:58:29 Re: A better translation version of Chinese forpsql/po/zh_CN.pofile
Previous Message Noah Misch 2015-09-21 05:33:14 Re: row_security GUC, BYPASSRLS