Scenario
A penetration tester connects to the production PostgreSQL instance from an external IP and successfully authenticates as postgres without any password. pg_hba.conf has a catch-all entry: host all all 0.0.0.0/0 trust. This was added during initial setup for “convenience” and never reviewed. The database has been publicly accessible with no authentication for 8 months.
How to Identify
Conditions:
pg_hba_file_rules shows auth_method = 'trust' for a TCP (host) rule
- The CIDR block is
0.0.0.0/0 (all IPs) or too broad
- Any external IP can connect as any user including
postgres
- PostgreSQL port 5432 is reachable from the internet (no firewall or security group)
Analysis Steps
-- Audit pg_hba.conf for permissive rules
SELECT line_num, type, database, user_name, address, netmask, auth_method
FROM pg_hba_file_rules
ORDER BY line_num;
-- Look for: auth_method='trust' with type='host' or broad CIDR
-- Find the most dangerous combinations:
SELECT line_num, type, database, user_name, address, auth_method,
CASE
WHEN auth_method = 'trust' AND type IN ('host','hostssl') THEN 'CRITICAL'
WHEN auth_method = 'trust' AND type = 'local' THEN 'MEDIUM'
WHEN address = '0.0.0.0' AND netmask = '0.0.0.0' THEN 'HIGH: all IPs'
ELSE 'OK'
END AS risk_level
FROM pg_hba_file_rules
WHERE auth_method IN ('trust', 'ident', 'password')
OR (address = '0.0.0.0' AND netmask = '0.0.0.0')
ORDER BY line_num;
-- Who is currently connected from external IPs?
SELECT pid, usename, client_addr, application_name, backend_start, state
FROM pg_stat_activity
WHERE client_addr IS NOT NULL
AND client_addr != '127.0.0.1'::inet
AND backend_type = 'client backend'
ORDER BY backend_start;
Pitfalls
host all all 0.0.0.0/0 trust is the most dangerous pg_hba.conf configuration possible — it allows anyone in the world to connect as any user with no credentials.
password authentication method (not md5 or scram-sha-256) sends the password in plaintext over the network — avoid it.
- Removing the permissive rule immediately disconnects current connections using it — this is the correct behavior, but warn operations teams first.
pg_hba.conf rules are evaluated in order — a later restrictive rule does nothing if an earlier permissive rule already matched.
- After fixing
pg_hba.conf, reload only (pg_reload_conf()) — existing connections are NOT re-authenticated until they reconnect.
Resolution Approach
Remove the broad trust rules immediately. Replace with specific hostssl rules scoped to known application IP ranges using scram-sha-256. Reload PostgreSQL configuration. Terminate any existing connections from the permissive rule’s scope that shouldn’t be there.