Scenario
During a security audit, the auditor finds that dev_user has SUPERUSER in the production database. Six months ago, a DBA granted it as a “quick fix” to let the developer run a one-time migration. It was never revoked. With SUPERUSER, dev_user can bypass Row-Level Security, read pg_authid (all password hashes), modify any table, and change server configuration.
How to Identify
Conditions:
pg_roles.rolsuper = true for a non-DBA role
- Role can
SET any GUC parameter, access pg_authid, bypass RLS policies
pg_hba.conf does not restrict SUPERUSER connections to local socket only
- No audit log of when/why SUPERUSER was granted
Analysis Steps
-- Find all superuser roles
SELECT rolname, rolsuper, rolcreaterole, rolcreatedb, rolreplication, rolcanlogin
FROM pg_roles
WHERE rolsuper = true
ORDER BY rolname;
-- Check if any non-DBA roles have dangerous attributes
SELECT rolname, rolsuper, rolcreaterole, rolbypassrls, rolreplication
FROM pg_roles
WHERE rolcanlogin = true
AND (rolsuper OR rolcreaterole OR rolbypassrls OR rolreplication)
ORDER BY rolname;
-- Check what tables/schemas the superuser role can access
-- (superuser bypasses all privilege checks — no need to check grants)
-- Check if superuser connections are restricted in pg_hba.conf
SELECT type, database, user_name, address, auth_method
FROM pg_hba_file_rules
WHERE 'all' = ANY(user_name)
OR EXISTS (
SELECT 1 FROM pg_roles
WHERE rolname = ANY(user_name) AND rolsuper
)
ORDER BY line_num;
Pitfalls
SUPERUSER bypasses all security checks: RLS, object privileges, pg_hba.conf checks, and even SECURITY DEFINER function restrictions.
- Revoking
SUPERUSER does not terminate existing sessions — the current session retains superuser until reconnection.
CREATEROLE alone can be dangerous: a role with CREATEROLE can grant itself membership in any non-superuser role, gaining all its privileges.
pg_hba.conf can restrict superuser connections to local socket only — this limits remote superuser access even if the role has SUPERUSER.
- The principle of least privilege: use
CREATEROLE, CREATEDB, or specific GRANT statements rather than SUPERUSER for legitimate administrative needs.
Resolution Approach
Immediately revoke SUPERUSER and replace with the minimum necessary privileges. Terminate existing sessions to enforce the change. Audit all roles for rolsuper, rolcreaterole, and rolbypassrls. Restrict superuser connections to Unix socket only in pg_hba.conf.