Thread: [PATCH] New predefined role pg_manage_extensions

[PATCH] New predefined role pg_manage_extensions

From
Michael Banck
Date:
Hi,

I propose to add a new predefined role to Postgres,
pg_manage_extensions. The idea is that it allows Superusers to delegate
the rights to create, update or delete extensions to other roles, even
if those extensions are not trusted or those users are not the database
owner.

I have attached a WIP patch for this.


Thoughts?

Michael

Attachment

Re: [PATCH] New predefined role pg_manage_extensions

From
Jelte Fennema-Nio
Date:
On Fri, 12 Jan 2024 at 15:53, Michael Banck <mbanck@gmx.net> wrote:
> I propose to add a new predefined role to Postgres,
> pg_manage_extensions. The idea is that it allows Superusers to delegate
> the rights to create, update or delete extensions to other roles, even
> if those extensions are not trusted or those users are not the database
> owner.

I agree that extension creation is one of the main reasons people
require superuser access, and I think it would be beneficial to try to
reduce that. But I'm not sure that such a pg_manage_extensions role
would have any fewer permissions than superuser in practice. Afaik
many extensions that are not marked as trusted, are not trusted
because they would allow fairly trivial privilege escalation to
superuser if they were.



Re: [PATCH] New predefined role pg_manage_extensions

From
Michael Banck
Date:
Hi,

On Fri, Jan 12, 2024 at 04:13:27PM +0100, Jelte Fennema-Nio wrote:
> But I'm not sure that such a pg_manage_extensions role would have any
> fewer permissions than superuser in practice. 

Note that just being able to create an extension does not give blanket
permission to use it. I did a few checks with things I thought might be
problematic like adminpack or plpython3u, and a pg_manage_extensions
user is not allowed to call those functions or use the untrusted
language.

> Afaik many extensions that are not marked as trusted, are not trusted
> because they would allow fairly trivial privilege escalation to
> superuser if they were.

While that might be true (or we err on the side of caution), I thought
the rationale was more that they either disclose more information about
the database server than we want to disclose to ordinary users, or that
they allow access to the file system etc.

I think if we have extensions in contrib that trivially allow
non-superusers to become superusers just by being installed, that should
be a bug and be fixed by making it impossible for ordinary users to
use those extensions without being granted some access to them in
addition.

After all, socially engineering a DBA into installing an extension due
to user demand would be a thing anyway (even if most DBAs might reject
it) and at least DBAs should be aware of the specific risks of a
particular extension probably?


Michael



Re: [PATCH] New predefined role pg_manage_extensions

From
Jelte Fennema-Nio
Date:
On Thu, 31 Oct 2024 at 22:47, Michael Banck <mbanck@gmx.net> wrote:
> Even though there has not been a lot of discussion on this, here is a
> rebased patch.  I have also added it to the upcoming commitfest.

After considering this again, I actually think this is a good change.
Basically all cloud providers already provide something similar. It
would be great if we could have a standardized way of doing this.

Regarding the actual patch: I think it looks good, but it needs some tests.



Re: [PATCH] New predefined role pg_manage_extensions

From
Kirill Reshke
Date:
On Fri, 1 Nov 2024 at 02:47, Michael Banck <mbanck@gmx.net> wrote:
>
> Hi,
>
> Even though there has not been a lot of discussion on this, here is a
> rebased patch.  I have also added it to the upcoming commitfest.


Hi!

> +       <literal>pg_manage_extensions</literal> allows creating, removing or
> +       updating extensions, even if the extensions are untrusted or the user is
> +       not the database owner.

Users are not required to be a database owner to create extensions.
They are required to have CREATE priv on database.

> On Sat, Jan 13, 2024 at 09:20:40AM +0100, Michael Banck wrote:
> > On Fri, Jan 12, 2024 at 04:13:27PM +0100, Jelte Fennema-Nio wrote:
> > > But I'm not sure that such a pg_manage_extensions role would have any
> > > fewer permissions than superuser in practice.
> >
> > Note that just being able to create an extension does not give blanket
> > permission to use it. I did a few checks with things I thought might be
> > problematic like adminpack or plpython3u, and a pg_manage_extensions
> > user is not allowed to call those functions or use the untrusted
> > language.
> >
> > > Afaik many extensions that are not marked as trusted, are not trusted
> > > because they would allow fairly trivial privilege escalation to
> > > superuser if they were.
> >
> > While that might be true (or we err on the side of caution), I thought
> > the rationale was more that they either disclose more information about
> > the database server than we want to disclose to ordinary users, or that
> > they allow access to the file system etc.

Extension installation script can execute arbitrary code with
superuser privilege if markled trusted.

Take this example

```

reshke@yezzey-cbdb:~/postgres/contrib/fooe$ cat fooe.control
# fooe extnesion
comment = 'foo bar baz'
default_version = '1.0'
module_pathname = '$libdir/fooe'
relocatable = true
trusted = true
reshke@yezzey-cbdb:~/postgres/contrib/fooe$ cat fooe--1.0.sql
/* contrib/fooe/fooe--1.0.sql */

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION fooe" to load this file. \quit


CREATE ROLE pwned WITH LOGIN SUPERUSER;

reshke@yezzey-cbdb:~/postgres/contrib/fooe$ ../../pgbin/bin/psql -d db2
db2=# create role user_no_sup with login;
CREATE ROLE
db2=# ^C
\q

reshke@yezzey-cbdb:~/postgres/contrib/fooe$ ../../pgbin/bin/psql -U
user_no_sup -d db2
psql (18devel)
Type "help" for help.

db2=> create extension fooe ;
CREATE EXTENSION
db2=> \du+
                                     List of roles
  Role name  |                         Attributes
   | Description
-------------+------------------------------------------------------------+-------------
 pwned       | Superuser                                                  |
 reshke      | Superuser, Create role, Create DB, Replication, Bypass RLS |
 user1       |                                                            |
 user2       |                                                            |
 user_no_sup |                                                            |

db2=> ^C

```


> > I think if we have extensions in contrib that trivially allow
> > non-superusers to become superusers just by being installed, that should
> > be a bug and be fixed by making it impossible for ordinary users to
> > use those extensions without being granted some access to them in
> > addition.
> >
> > After all, socially engineering a DBA into installing an extension due
> > to user demand would be a thing anyway (even if most DBAs might reject
> > it) and at least DBAs should be aware of the specific risks of a
> > particular extension probably?
>
>
> Michael


In general, this concept is rather dubious. Why should we have such a
dangerous pre-defined role? I would prefer to have complete control
over what gets installed in the database if I were a superuser.
Additionally, if a dangerous extension is inadvertently or otherwise
loaded on the host, I never want a normal user to run code with
superuser privileges.

For a thorough understanding of the current situation and the
rationale behind the design, you can read this[1] discussion.


[1] https://www.postgresql.org/message-id/5889.1566415762%40sss.pgh.pa.us

-- 
Best regards,
Kirill Reshke



Re: [PATCH] New predefined role pg_manage_extensions

From
Kirill Reshke
Date:
On Mon, 18 Nov 2024 at 11:26, Kirill Reshke <reshkekirill@gmail.com> wrote:
>
> On Fri, 1 Nov 2024 at 02:47, Michael Banck <mbanck@gmx.net> wrote:
> >
> > Hi,
> >
> > Even though there has not been a lot of discussion on this, here is a
> > rebased patch.  I have also added it to the upcoming commitfest.
>
>
> Hi!
>
> > +       <literal>pg_manage_extensions</literal> allows creating, removing or
> > +       updating extensions, even if the extensions are untrusted or the user is
> > +       not the database owner.
>
> Users are not required to be a database owner to create extensions.
> They are required to have CREATE priv on database.
>
> > On Sat, Jan 13, 2024 at 09:20:40AM +0100, Michael Banck wrote:
> > > On Fri, Jan 12, 2024 at 04:13:27PM +0100, Jelte Fennema-Nio wrote:
> > > > But I'm not sure that such a pg_manage_extensions role would have any
> > > > fewer permissions than superuser in practice.
> > >
> > > Note that just being able to create an extension does not give blanket
> > > permission to use it. I did a few checks with things I thought might be
> > > problematic like adminpack or plpython3u, and a pg_manage_extensions
> > > user is not allowed to call those functions or use the untrusted
> > > language.
> > >
> > > > Afaik many extensions that are not marked as trusted, are not trusted
> > > > because they would allow fairly trivial privilege escalation to
> > > > superuser if they were.
> > >
> > > While that might be true (or we err on the side of caution), I thought
> > > the rationale was more that they either disclose more information about
> > > the database server than we want to disclose to ordinary users, or that
> > > they allow access to the file system etc.
>
> Extension installation script can execute arbitrary code with
> superuser privilege if markled trusted.
>
> Take this example
>
> ```
>
> reshke@yezzey-cbdb:~/postgres/contrib/fooe$ cat fooe.control
> # fooe extnesion
> comment = 'foo bar baz'
> default_version = '1.0'
> module_pathname = '$libdir/fooe'
> relocatable = true
> trusted = true
> reshke@yezzey-cbdb:~/postgres/contrib/fooe$ cat fooe--1.0.sql
> /* contrib/fooe/fooe--1.0.sql */
>
> -- complain if script is sourced in psql, rather than via CREATE EXTENSION
> \echo Use "CREATE EXTENSION fooe" to load this file. \quit
>
>
> CREATE ROLE pwned WITH LOGIN SUPERUSER;
>
> reshke@yezzey-cbdb:~/postgres/contrib/fooe$ ../../pgbin/bin/psql -d db2
> db2=# create role user_no_sup with login;
> CREATE ROLE
> db2=# ^C
> \q
>
I'm sorry, the example is incomplete.

Here is missing command:

db2=# grant create on database db2 to user_no_sup ;
GRANT



> reshke@yezzey-cbdb:~/postgres/contrib/fooe$ ../../pgbin/bin/psql -U
> user_no_sup -d db2
> psql (18devel)
> Type "help" for help.
>
> db2=> create extension fooe ;
> CREATE EXTENSION
> db2=> \du+
>                                      List of roles
>   Role name  |                         Attributes
>    | Description
> -------------+------------------------------------------------------------+-------------
>  pwned       | Superuser                                                  |
>  reshke      | Superuser, Create role, Create DB, Replication, Bypass RLS |
>  user1       |                                                            |
>  user2       |                                                            |
>  user_no_sup |                                                            |
>
> db2=> ^C
>
> ```
>
>
> > > I think if we have extensions in contrib that trivially allow
> > > non-superusers to become superusers just by being installed, that should
> > > be a bug and be fixed by making it impossible for ordinary users to
> > > use those extensions without being granted some access to them in
> > > addition.
> > >
> > > After all, socially engineering a DBA into installing an extension due
> > > to user demand would be a thing anyway (even if most DBAs might reject
> > > it) and at least DBAs should be aware of the specific risks of a
> > > particular extension probably?
> >
> >
> > Michael
>
>
> In general, this concept is rather dubious. Why should we have such a
> dangerous pre-defined role? I would prefer to have complete control
> over what gets installed in the database if I were a superuser.
> Additionally, if a dangerous extension is inadvertently or otherwise
> loaded on the host, I never want a normal user to run code with
> superuser privileges.
>
> For a thorough understanding of the current situation and the
> rationale behind the design, you can read this[1] discussion.
>
>
> [1] https://www.postgresql.org/message-id/5889.1566415762%40sss.pgh.pa.us
>
> --
> Best regards,
> Kirill Reshke



-- 
Best regards,
Kirill Reshke



Re: [PATCH] New predefined role pg_manage_extensions

From
Michael Banck
Date:
Hi,

first, sorry for the late reply :-/

On Mon, Nov 18, 2024 at 11:26:40AM +0500, Kirill Reshke wrote:
> On Fri, 1 Nov 2024 at 02:47, Michael Banck <mbanck@gmx.net> wrote:
> > Even though there has not been a lot of discussion on this, here is a
> > rebased patch.  I have also added it to the upcoming commitfest.
> >
> > +       <literal>pg_manage_extensions</literal> allows creating, removing or
> > +       updating extensions, even if the extensions are untrusted or the user is
> > +       not the database owner.
> 
> Users are not required to be a database owner to create extensions.
> They are required to have CREATE priv on database.

Ah right, thanks, I have changed that.

> > On Sat, Jan 13, 2024 at 09:20:40AM +0100, Michael Banck wrote:
> > > On Fri, Jan 12, 2024 at 04:13:27PM +0100, Jelte Fennema-Nio wrote:
> > > > But I'm not sure that such a pg_manage_extensions role would have any
> > > > fewer permissions than superuser in practice.
> > >
> > > Note that just being able to create an extension does not give blanket
> > > permission to use it. I did a few checks with things I thought might be
> > > problematic like adminpack or plpython3u, and a pg_manage_extensions
> > > user is not allowed to call those functions or use the untrusted
> > > language.
> > >
> > > > Afaik many extensions that are not marked as trusted, are not trusted
> > > > because they would allow fairly trivial privilege escalation to
> > > > superuser if they were.
> > >
> > > While that might be true (or we err on the side of caution), I thought
> > > the rationale was more that they either disclose more information about
> > > the database server than we want to disclose to ordinary users, or that
> > > they allow access to the file system etc.
> 
> Extension installation script can execute arbitrary code with
> superuser privilege if markled trusted.
> 
> Take this example

[...]

Right, but this implies that a superuser installed that
rogue/sketchy/unsafe-but-declared-safe extension in the first place.
I would assume that the person having pg_manage_extensions privs not
have the ability to install extensions at the system level. Maybe this
should be cautioned some more in the documentation part of this patch,
though.

Unless one of the current untrusted contrib extensions allows to attain
superuser rights by being created?

My opinion was that superusers (or system administrators) would need to
explicitly install this (presumably external) extension somehow, either
via package management or by compile-installing it. So, what is the
threat vector here? I think the system administrator has (in most/all(?)
cases) superuser access to Postgres in practise anyway, via sudo/root
access to the postgres user.

Maybe this should be revisited in light of the extension_destdir GUC
patch, but I think in that case the system admins/postgres superuser
should make sure that this auxiliary directory is not writable to
others.

> In general, this concept is rather dubious. Why should we have such a
> dangerous pre-defined role?

Well, I would say pg_execute_server_program could be regarded as a
precedent.

> I would prefer to have complete control over what gets installed in
> the database if I were a superuser.

A superuser will have to grant this attribute to somebody, so there is
certainly some gate-keeping here.

As a side note, maybe what we are missing is a way for site admins to
disable some of the predefined roles (i.e. something better than just
DELETE FROM pg_authid).

> Additionally, if a dangerous extension is inadvertently or otherwise
> loaded on the host, I never want a normal user to run code with
> superuser privileges.

Well again, normal users with pg_execute_server_program rights can
basically already do this. I would consider a user with a
pg_manage_extensions right not a normal user, but an application DBA
or a pseudo-superuser in the managed Postgres cloud parlance.
 
> For a thorough understanding of the current situation and the
> rationale behind the design, you can read this[1] discussion.

I have re-read this since, thanks.

I do think having a whitelist of allowed-to-be-installed extensions
(similar/like https://github.com/dimitri/pgextwlist) makes sense
additionally in today's container/cloud word where the local Postgres
admin might not have control over which packages get installed but wants
to have control over which extension the application admins (or whoever)
may create, but that is another topic I think.


Michael