-
-
Notifications
You must be signed in to change notification settings - Fork 13
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
Allow using event triggers without SUPERUSER #67
Comments
I gave this a shot but I was surprised to find @soedirgo Which role should we switch to create the event trigger? Why |
Here it says Lines 284 to 286 in fa39431
@soedirgo What's the relationship between these 2 roles? |
Agree that |
Before you go ahead with the implementation, keep in mind that simply switching to a superuser to perform the |
So we could say that the
Clarifying that on #99. |
Checking how this works on RDS: CREATE OR REPLACE FUNCTION become_super()
RETURNS event_trigger
LANGUAGE plpgsql AS
$$
BEGIN
RAISE NOTICE 'Transforming % to superuser', current_user;
ALTER ROLE current_user SUPERUSER;
END;
$$;
CREATE EVENT TRIGGER event_trigger_2
ON ddl_command_end
EXECUTE PROCEDURE become_super();
postgres=> \dy
List of event triggers
Name | Event | Owner | Enabled | Function | Tags
-----------------+-----------------+----------+---------+--------------+------
event_trigger_2 | ddl_command_end | rdsadmin | enabled | become_super | postgres=> select current_user;
current_user
--------------
postgres
(1 row)
postgres=> create table foo();
NOTICE: Transforming postgres to superuser
ERROR: permission denied to alter role
DETAIL: Only roles with the SUPERUSER attribute may change the SUPERUSER attribute.
CONTEXT: SQL statement "ALTER ROLE current_user SUPERUSER"
PL/pgSQL function become_super() line 4 at SQL statement So the event trigger SQL is ran as the Now, using the implementation on #98: $ supautils-with-pg-14 psql -U privileged_role
CREATE OR REPLACE FUNCTION become_super()
RETURNS event_trigger
LANGUAGE plpgsql AS
$$
BEGIN
RAISE NOTICE 'Transforming % to superuser', current_user;
ALTER ROLE current_user SUPERUSER;
END;
$$;
CREATE EVENT TRIGGER event_trigger_2
ON ddl_command_end
EXECUTE PROCEDURE become_super();
postgres=> \dy
List of event triggers
Name | Event | Owner | Enabled | Function | Tags
-----------------+-----------------+----------+---------+--------------+------
event_trigger_2 | ddl_command_end | postgres | enabled | become_super |
(1 row)
postgres=> select current_user;
current_user
-----------------
privileged_role
(1 row)
postgres=> create table foo();
2025-01-14 18:01:07.922 -05 [435306] ERROR: permission denied to alter role
2025-01-14 18:01:07.922 -05 [435306] DETAIL: Only superusers can alter privileged roles.
2025-01-14 18:01:07.922 -05 [435306] CONTEXT: SQL statement "ALTER ROLE privileged_role SUPERUSER"
PL/pgSQL function become_super() line 4 at SQL statement
2025-01-14 18:01:07.922 -05 [435306] STATEMENT: create table foo();
NOTICE: Transforming privileged_role to superuser
ERROR: permission denied to alter role
DETAIL: Only superusers can alter privileged roles.
CONTEXT: SQL statement "ALTER ROLE privileged_role SUPERUSER"
PL/pgSQL function become_super() line 4 at SQL statement So the behavior is the same as RDS, the event trigger is ran as the current user not the owner.
@soedirgo So is the above true at all? If the event trigger is ran as the current user, then no privilege escalation can happen? (since the user will execute the SQL with its current privileges) Or am I'm missing something? (Ideally we would have a clear test case for this, it took me a long time to parse the pg email thread and I didn't seem to gain much as compared to just messing with RDS) |
Here's an example using the implementation in #98
The privesc happens not when the malicious role trips over the event trigger, it happens when the internal admin role trips over it. Replace |
Thanks for clarifying. Do we expect something to be run directly by the
Possible fixes
|
Thinking more about privesc. The essential problem here is that once a user creates an event trigger, it runs globally for every role. And this impacts superuser and also This would imply that (It also occurs me that we an extra check would be good: there should only be one superuser per database cluster. This also seems like a best practice.) |
Problem
Currently there's no way to use event triggers. RDS allows it though, see https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL.Concepts.General.FeatureSupport.EventTriggers.html. Caveat: the user must delete event triggers when migrating to a new major postgres version.
References:
Solution
Allow event triggers for non superusers.
The text was updated successfully, but these errors were encountered: