Subject: Re: prevent users from SELECT-ing from pg_roles/pg_database

From: Andreas Joseph Krogh <[email-masked]>
Date: Mon, 27 May 2024 09:33:51 +0200 (CEST)

På fredag 24. mai 2024 kl. 19:02:13, skrev Tom Lane <[email-masked] 
<mailto:[email-masked]>>:
Andreas Joseph Krogh <[email-masked]> writes:
> Hi, is there a way to prevent a user/role from SELECT-ing from certain 
> system-tables?
> I'd like the contents of pg_{user,roles,database} to not be visible to all 
> users.

As noted, you can in principle revoke the public SELECT grant from
those views/catalogs. However, the system is not designed to hide
such information, which means you'll have (at least) two kinds of
issues to worry about:

1. Queries or tools breaking that you didn't expect to break.
It's hardly uncommon for instance for queries on pg_class to
join to pg_roles to get the owner names for tables.

2. Information leaks. For example, mapping role OID to role name
is trivial with either regrole or pg_get_userbyid(), so it
wouldn't take long to scan the plausible range of role OIDs and
get all their names, even without SQL access to the underlying
catalog.

regards, tom lane

I tried:
REVOKE SELECT ON pg_catalog.pg_database FROM public;
But that doesn't prevent a normal user from querying pg_database it seems…

--
Andreas Joseph Krogh
CTO / Partner - Visena AS
Mobile: +47 909 56 963
[email-masked] <mailto:[email-masked]>
www.visena.com <https://www.visena.com>
 <https://www.visena.com>

---

From: Laurenz Albe <[email-masked]>
Date: Mon, 27 May 2024 11:10:10 +0200

> But that doesn't prevent a normal user from querying pg_database it seems…

It works here.

Perhaps the "normal" user is a member of "pg_read_all_data".

Yours,
Laurenz Albe

---

From: Andreas Joseph Krogh <[email-masked]>
Date: Mon, 27 May 2024 11:33:30 +0200 (CEST)

På mandag 27. mai 2024 kl. 11:10:10, skrev Laurenz Albe <
[email-masked] <mailto:[email-masked]>>:

It works here.

Yours,
Laurenz Albe

Don't think so:
andreak@[local]:5432 16.3 andreak=# REVOKE pg_read_all_data from nisse; 
WARNING: role "nisse" has not been granted membership in role 
"pg_read_all_data" by role "postgres" REVOKE ROLE

Any hints welcome.

---

From: Laurenz Albe <[email-masked]>
Date: Mon, 27 May 2024 12:45:02 +0200

On Mon, 2024-05-27 at 11:33 +0200, Andreas Joseph Krogh wrote:
> På mandag 27. mai 2024 kl. 11:10:10, skrev Laurenz Albe <[email-masked]>:
> WARNING:  role "nisse" has not been granted membership in role "pg_read_all_data" by role "postgres"
> REVOKE ROLE

Possibilities:

- you are running a modified version of PostgreSQL
- you are actually a superuser, perhaps by inheritance

Yours,
Laurenz Albe

---

From: Tom Lane <[email-masked]>
Date: Mon, 27 May 2024 16:48:17 -0700

> It works here.

Works for me too, although you'd have to do it over in each
database where you want it to be effective.  (Although
pg_database is a shared catalog, the metadata about it
is not shared.)

			regards, tom lane

---

From: Andreas Joseph Krogh <[email-masked]>
Date: Tue, 28 May 2024 08:07:38 +0200 (CEST)

På tirsdag 28. mai 2024 kl. 01:48:17, skrev Tom Lane <[email-masked] 
<mailto:[email-masked]>>:

regards, tom lane

Ah, that's what I was missing. Thanks for pointing that out, it's working as 
expected now.