PostgreSQL exposed to the internet
A PostgreSQL cluster reachable from an untrusted network is a different risk
from an open Redis. Postgres does authenticate
by default, so an exposed cluster is not automatically compromised — it is
automatically under attack, and the outcome depends entirely on what
pg_hba.conf says.
The two failure modes are worth separating, because they need different reactions.
Failure mode one: trust
Section titled “Failure mode one: trust”If any rule uses trust with an address an
attacker can reach, there is no attack to speak of. They connect as postgres
and it is over. No guessing, no exploit — the configuration invited them.
This is rare on the public internet and common on “internal” networks that turn out to be less internal than assumed: a VPC shared with another tenant, a container network, a VPN with wide membership.
Failure mode two: a guessable password
Section titled “Failure mode two: a guessable password”With scram-sha-256 and a wide host all all 0.0.0.0/0 rule, what you have is a
brute-force target. Postgres has no built-in rate limiting and no account
lockout — it will answer authentication attempts as fast as they arrive, forever.
Weak passwords fall; strong ones don’t.
Why superuser is the whole game
Section titled “Why superuser is the whole game”Both modes matter more than “someone reads the database”, because a superuser connection is not confined to the database:
COPY ... FROM PROGRAM 'command'executes a shell command as thepostgresOS user. That is a shell, reached over port 5432.pg_read_file()/pg_read_binary_file()read files from the host filesystem.CREATE EXTENSIONor an untrusted PL can load code.- Superuser bypasses every permission check, including row-level security.
So “we don’t keep anything sensitive in that database” is the same mistake as with Redis. The data is not the prize; the host is. And it is why not connecting as superuser matters even inside a trusted network — it decides whether an injection is a data problem or a host problem.
The shortest path from exposed to closed
Section titled “The shortest path from exposed to closed”- Remove trust — nothing else matters while it is there.
- Scope pg_hba.conf — replace
0.0.0.0/0with the addresses that actually connect. This is the control that closes it. - Firewall 5432 — same reasoning as everywhere else: an unreachable daemon needs no password.
- Stop connecting as superuser — bounds the damage of everything above going wrong.
Steps 1 and 2 are a pg_hba.conf edit and a reload. No restart, no downtime for
established connections.
Related
Section titled “Related”- Hardening PostgreSQL — the full checklist.
- Remove trust authentication — the rule that turns exposure into compromise.