PostgreSQL Superuser and Dangerous Privilege Detection
PostgreSQL privilege levels determine which exploitation techniques are available. A superuser account enables COPY FROM PROGRAM for OS command execution, pg_read_file for arbitrary file reads, and extension loading for persistent backdoors. CREATEROLE enables creating new superuser accounts. Excessive schema or table grants on application accounts expose data even without superuser. Identifying exactly what privileges the current session holds determines the correct exploitation path before attempting anything active.
Check Current Session Privileges
Run this immediately after obtaining any valid connection:
rolname | rolsuper | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication ----------+----------+---------------+-------------+-------------+---------------- appuser | f | f | f | t | f
What each attribute enables:
- rolsuper = t — superuser, bypasses all permission checks. COPY FROM PROGRAM, pg_read_file, and extension loading all work. This is the highest value result.
- rolcreaterole = t — can create new roles including superuser roles. Privilege escalation path even without current superuser status.
- rolcreatedb = t — can create databases. Less directly exploitable but allows creating databases where extensions can be loaded.
- rolreplication = t — replication privilege. Can connect to the replication stream and read all committed data as it is written.
Enumerate All Roles and Their Privileges
Map every role in the database to identify misconfigured accounts with excessive privileges:
rolname | rolsuper | rolcreaterole | rolcreatedb | rolcanlogin ------------------+----------+---------------+-------------+------------- postgres | t | t | t | t pg_monitor | f | f | f | f appuser | f | f | f | t backup | f | t | f | t
A non-superuser account with rolcreaterole = t like the backup account above can create a new superuser. This is a privilege escalation path — covered in the privilege escalation phase.
Check Role Membership and Inheritance
Privileges can be inherited through role membership. A user who is a member of a superuser role inherits those privileges if inheritance is enabled:
If the current user is a member of a role with superuser and the membership has admin_option = t, the SET ROLE command can be used to assume that role's privileges in the current session.
Check Table and Schema-Level Grants
Even without superuser, excessive grants on application tables allow direct data access:
Tables with SELECT granted to PUBLIC or to the current user are directly readable. Tables with INSERT, UPDATE, or DELETE granted enable data manipulation without needing superuser. Check for grants on tables named users, accounts, tokens, or api_keys first.
References
-
PostgreSQL — Role attributeswww.postgresql.org/docs/current/role-attributes.html (opens in new tab)
Full reference for rolsuper, rolcreaterole, rolcreatedb, and rolreplication
-
PostgreSQL — Role membershipwww.postgresql.org/docs/current/role-membership.html (opens in new tab)
Role inheritance, SET ROLE, and admin_option behavior reference
Was this helpful?
Your feedback helps improve this page.