Re: has_privs_of_role vs. is_member_of_role, redux

From: Joe Conway <mail(at)joeconway(dot)com>
To: Robert Haas <robertmhaas(at)gmail(dot)com>, "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: has_privs_of_role vs. is_member_of_role, redux
Date: 2022-08-25 19:03:27
Message-ID: a4838283-d7ee-de19-1dc8-9083eb19a405@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 8/25/22 12:12, Robert Haas wrote:
> So far, so good. But it's clearly not the case that "GRANT stuff TO
> robert" has conferred no privileges at all on robert. At the very
> least, it's enabled him to "SET ROLE stuff", but what else? I decided
> to go through the code and make a list of the things that robert can
> now do that he couldn't do before. Here it is:
>
> 1. robert can create new objects of various types owned by stuff:

> 2. robert can change the owner of objects he owns to instead be owned by stuff:

> 3. robert can change the default privileges for stuff:

> 4. robert can execute "SET ROLE stuff".

Nice analysis, and surprising (to me)

> I argue that #3 is a clear bug. robert can't select from stuff's
> tables or change privileges on stuff's objects, so why can he change
> stuff's default privileges? is_member_of_role() has a note that it is
> not to be used for privilege checking, and this seems like it's pretty
> clearly a privilege check.

+1 this feels very wrong to me

> On the flip side, #4 is pretty clearly correct. Presumably, allowing
> that to happen was the whole point of executing "GRANT stuff TO
> robert" in the first place.

Exactly

> The other two are less clear, in my opinion. We don't want users to
> end up owning objects that they didn't intend to own; in particular,
> if any user could make a security-definer function and then gift it to
> the superuser, it would be a disaster. So, arguably, the ability to
> make some other role the owner of an object represents a privilege
> that your role holds with respect to their role. Under that theory,
> the is_member_of_role() checks that are performed in cases #1 and #2
> are privilege checks, and we ought to be using has_privis_of_role()
> instead, so that a non-inherited role grant doesn't confer those
> privileges. But I don't find this very clear cut, because except when
> the object you're gifting is a Trojan horse, giving stuff away helps
> the recipient, not the donor.
>
> Also, from a practical point of view, changing the owner of an object
> is different from other things that robert might want to do. If robert
> wants to create a table as user stuff or read some data from tables
> user stuff can access or change privileges on objects that role stuff
> owns, he can just execute "SET ROLE stuff" and then do any of that
> stuff. But he can't give away his own objects by assuming stuff's
> privileges. Either he can do it as himself, or he can't do it at all.
> It wouldn't be crazy IMHO to decide that a non-inherited grant isn't
> sufficient to donate objects to the granted role, and thus an
> inherited grant is required in such cases. However, the current system
> doesn't seem insane either, and in fact might be convenient in some
> situations.
>
> In short, my proposal is to change the ALTER DEFAULT PRIVILEGES code
> so that you have to have the privileges of the target role, not jut
> membership in the target role, and leave everything else unchanged.
>
> Thoughts?

I'm not sure about these last two. Does it matter that object creation
is being logged, maybe for auditing purposes, under a different user
than the owner of the object?

--
Joe Conway
PostgreSQL Contributors Team
RDS Open Source Databases
Amazon Web Services: https://aws.amazon.com

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2022-08-25 19:15:27 Re: pg_stat_bgwriter.buffers_backend is pretty meaningless (and more?)
Previous Message Magnus Hagander 2022-08-25 18:45:05 Re: pg_receivewal and SIGTERM