New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add pg_authid view #6600
base: main
Are you sure you want to change the base?
Add pg_authid view #6600
Conversation
@jnidzwetzki, @mkindahl: please review this pull request.
|
-- View for viewing non-superuser passwords | ||
CREATE OR REPLACE VIEW timescaledb_information.pg_authid | ||
WITH (security_barrier = true) AS | ||
SELECT * FROM pg_catalog.pg_authid WHERE rolsuper = 'false'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to make this something fancier, e.g. to exclude replication users, roles with expired passwords, etc.
Hi @adriangb and thank you for the contribution! What I do not understand is what this new view would give that |
The password in My primary use case is to use it with pgbouncer for |
Well... there is a risk that you expose passwords that should not be exposed, so the view need to make sure to filter out users that it should not be able to view. Look at this as an example of why creating a view on mats=# create user nobody;
CREATE ROLE
mats=# create user big_boss password 'xyzzy';
CREATE ROLE
mats=# select rolname, rolpassword from pg_authid where rolname in ('nobody', 'big_boss');
rolname | rolpassword
----------+---------------------------------------------------------------------------------------------------------------------------------------
nobody | [NULL]
big_boss | SCRAM-SHA-256$4096:lsy3j3SwAq1oek+jCDUtXQ==$1xwEu5WjIHODQPDziQtWKN2Ujwlt3BeHggTCQayLr3I=:puzhnWt7w1jYQgIr9fDzEmIGR3O0cqRyuGc/gEeD5aw=
(2 rows)
mats=# create view leaky as select * from pg_authid;
CREATE VIEW
mats=# grant all on leaky to public ;
GRANT
mats=# set role nobody;
SET
mats=> select rolname, rolpassword from leaky where rolname in ('nobody', 'big_boss');
rolname | rolpassword
----------+---------------------------------------------------------------------------------------------------------------------------------------
nobody | [NULL]
big_boss | SCRAM-SHA-256$4096:lsy3j3SwAq1oek+jCDUtXQ==$1xwEu5WjIHODQPDziQtWKN2Ujwlt3BeHggTCQayLr3I=:puzhnWt7w1jYQgIr9fDzEmIGR3O0cqRyuGc/gEeD5aw=
(2 rows)
Correct, passwords should not be exposed unnecessarily, not even hashes of passwords. |
I understand the example but maybe I'm missing what it proves. What I want is for Can't we make this view only accessible to |
Yes, that is possible, but it requires additional measures in place. In essence, you need to make sure that the view only shows passwords that the Note that only users that belong to the Also note that there are still risks involved with this since you are sending the password over the network so it is necessary to make sure that you have an encrypted connection to the database. |
Agreed. I'm not sure how you'd define that, I went with "any non-superuser".
Of course. If you're setting up a connection pooler it's either this or you store the passwords in plaintext on the connection pooler, which seems much more unsafe and inflexible. |
@adriangb We're happy to accept the contribution, but in order for this to not introduce a security issue, we would need the following changes:
|
Do you mean that a user can only see their own password? The whole point is that you can have a user (lets say |
Well, no, of course not, but the user should not be allowed to see passwords for accounts that it is not explicitly granted permission to view. For example, if it is a non-superuser, it should not be allowed to see passwords of superusers (which you're handling). We need something similar for handling non-superuser admin users as well. If you have tests set up and try to do something similar to how it works for I realize that the "requirement" is a little vague, but I think you get the gist. We do not want to expose passwords or hashes to users that are not allowed to view them. |
This needs a bit more design, referring to a blog post here We could come up with a security definer functions that is limiting the allowed hashes. For example, something like: CREATE FUNCTION public.get_password_hash (
INOUT user name,
OUT password text
) RETURNS record
LANGUAGE sql SECURITY DEFINER SET search_path = pg_catalog AS
$$SELECT usename, passwd FROM pg_catalog.pg_shadow WHERE usename = user AND pg_catalog.pg_has_role(user, 'member') $$; However, I'm not sure if we want to make this change to timescaledb. What problem are you solving exactly? |
As per some of the comments above I was trying to set up pgbouncer myself (for reasons I don't think it's worth getting into) and to do that you either need to put all of the passwords in a text file and keep them updated or use
Precisely, let's consider the use case in that blog post. CREATE FUNCTION public.lookup (
INOUT p_user name,
OUT p_password text
) RETURNS record
LANGUAGE sql SECURITY DEFINER SET search_path = pg_catalog AS
$$SELECT usename, passwd FROM pg_authid WHERE usename = p_user$$; Because no user, not even As per the article:
Thus my goal here was to make a view that excludes superuser passwords but is still only accessible to the timescale cloud equivalent of a superuser which would be REVOKE ALL ON timescaledb_information.pg_authid FROM public;
GRANT SELECT ON timescaledb_information.pg_authid TO tsdbadmin; Or something like that. The goal being that when logged in as |
@adriangb a security definer function (as above) runs in the security context of the user that created it ( Therefore, access to The usefulness of the function is that it clearly creates a boundary where we switch from a regular user to a superuser.
That's why we could create such a function as a superuser, and grant execute on that function to check the topic |
Yes I know that. But
Maybe I'm missing something but the code snippit in my previous comment was literally copied from that section. |
It's still not clear to me what the missing discussion or design is here. I just want to have |
Add a view to replace
pg_catalog.pg_authid