logo

Port 5432 – PostgreSQL

Service:

PostgreSQL

Protocol:

TCP

Port:

5432

Used for:

Client connections to PostgreSQL relational database servers

Port 5432 is the default port for PostgreSQL database servers — the TCP port the postgres backend listens on for client connections carrying authentication, SQL queries, and result sets. PostgreSQL (often just “Postgres”) is one of the most widely deployed open-source relational databases, and the same port and wire protocol are used by managed variants like Amazon RDS/Aurora for PostgreSQL and Azure Database for PostgreSQL, and by forks such as EnterpriseDB. A database should almost never be reachable from the internet, which is exactly why an exposed port 5432 is one of the highest-value findings on a network: authenticate, and you’re usually one step from reading every table — and, as a superuser, from command execution on the host.

Why It’s Open

PostgreSQL sits behind a huge share of modern web apps, analytics platforms, and backend services, so port 5432 turns up wherever Postgres is the database of record. In a healthy design the database lives on a private network or the same host as the app and only ever answers on localhost or an internal address. The port becomes a problem when listen_addresses is set to * and it’s bound to 0.0.0.0 and left open to the world — a default in some container images and quick-start guides, a leftover from a debugging session, or the result of a cloud security group that’s wider than anyone intended. Where PostgreSQL is exposed, its siblings often are too: check for MySQL/MariaDB on port 3306, Microsoft SQL Server on 1433, Oracle on 1521, MongoDB on 27017, Redis on 6379, and the MySQL X Protocol on port 33060.

Common Risks

  • trust authentication (no password). The classic PostgreSQL misconfiguration. A pg_hba.conf line whose method is trust accepts any connection for the matched user with no password at all. Pair that with an exposed port and anyone who can reach 5432 is logged straight in — often as the postgres superuser.
  • Blank, default, or weak superuser password. The built-in postgres superuser with no password, a well-known default, or something guessable is instant full control of every database on the server.
  • Over-broad host rules. A host all all 0.0.0.0/0 line in pg_hba.conf accepts connections from any address, so a single weak credential is reachable from the whole internet.
  • Exposed to the internet. PostgreSQL was never meant to face the public network. Once 5432 is reachable it’s subject to constant automated brute-forcing and mass-ransomware and cryptomining campaigns.
  • Superuser to OS command execution. A superuser can run operating-system commands via COPY ... FROM PROGRAM, and historically via C-language user-defined functions and the large-object lo_import/lo_export file read/write primitives — turning database access into a full host compromise.
  • Password hash disclosure. A superuser can read pg_shadow / pg_authid and dump every role’s stored MD5 or SCRAM-SHA-256 password hash for offline cracking.
  • Cleartext by default. Unless TLS is configured and required, credentials and query data cross the network unencrypted and can be sniffed on the path.
  • SQL injection landing here. Injection in a web app on port 80 or 443 ultimately executes against the PostgreSQL instance on 5432, so the two findings reinforce each other.

Want to save time on reporting?

Let PentestPad generate, track, and export your reports - automatically.

logo-cta

Enumeration & Testing

Detect the service and grab the version banner

Terminal window
nmap -sV -p 5432 <target>

Brute-force logins with the NSE script

Terminal window
nmap -p 5432 --script pgsql-brute <target>

pgsql-brute performs password guessing against PostgreSQL over the native protocol.

Connect with the native client

Terminal window
psql -h <target> -U postgres -c "\l"
SELECT version();
SELECT current_user, session_user;
\du -- list roles and attributes
SELECT usename, passwd FROM pg_shadow; -- superuser only: dump password hashes
SELECT datname FROM pg_database; -- list databases

Brute-force with Hydra

Terminal window
hydra -L users.txt -P passwords.txt postgres://<target>

Metasploit modules

Terminal window
msfconsole -q
# Version fingerprint
use auxiliary/scanner/postgres/postgres_version
set RHOSTS <target>
run
# Credential brute-force
use auxiliary/scanner/postgres/postgres_login
set RHOSTS <target>
run
# Dump pg_shadow/pg_authid password hashes for offline cracking
use auxiliary/scanner/postgres/postgres_hashdump
set RHOSTS <target>
run

Post-authentication enumeration and command execution

Terminal window
# Dump the database schema
use auxiliary/scanner/postgres/postgres_schemadump
# Run arbitrary SQL through a URI connection string
use auxiliary/admin/postgres/postgres_sql
# Superuser: run OS commands via COPY ... FROM PROGRAM
use exploit/multi/postgres/postgres_copy_from_program_cmd_exec
# Superuser: UDF payload on a default Linux install (pg_largeobject → shared object)
use exploit/linux/postgres/postgres_payload

Dumped hashes crack offline with hashcat — mode 12 for the older md5 format from pg_shadow, mode 28600 for SCRAM-SHA-256 — or with John the Ripper. Log every open instance, working credential, and dumped hash as you go so it lands in the pentest report instead of a scratch terminal.

What to Look For

Checkpoint What it means
trust method in pg_hba.conf No password required — instant login for the matched user
postgres superuser with blank/weak password Full control of every database — critical
host all all 0.0.0.0/0 rule Reachable from anywhere; over-broad by default
Your session role is a superuser COPY ... FROM PROGRAM gives OS command execution
pg_shadow / pg_authid readable Dump MD5 / SCRAM-SHA-256 hashes for offline cracking
pg_execute_server_program granted to a role Non-superusers can also run OS commands via COPY
No SSL negotiated Credentials and queries sniffable on the wire
Old, unpatched minor version in banner Check for version-specific privesc / RCE CVEs

Known CVEs and Exploits

  • CVE-2019-9193 (disputed) — The signature PostgreSQL technique. In 9.3 through 11.2, COPY TO/FROM PROGRAM lets a superuser (or a role in pg_execute_server_program) run arbitrary OS commands as the database’s operating-system user. The PostgreSQL project disputes this as a CVE, arguing it’s intended superuser functionality — a superuser can already run commands by other means — and the original reporters asked for it to be retracted. It’s still worth knowing because it’s the fastest database-to-host pivot on an exposed instance, and it’s weaponised as Metasploit’s exploit/multi/postgres/postgres_copy_from_program_cmd_exec and Exploit-DB 46813. CVSS 3.0 7.2, CWE-78.
  • CVE-2018-1058 — Search-path / public schema function hijack. A user who can create objects in a schema on the search_path (typically the world-writable public schema) can plant a function that shadows a built-in, so it runs with the privileges of another user — up to superuser — when they execute an affected query. Affects PostgreSQL 9.3 through 10; the fix changed default public schema permissions and search_path guidance. CVSS 3.1 8.8, CWE-20.
  • CVE-2024-10979 — PL/Perl environment-variable RCE. Incorrect control of environment variables in PostgreSQL PL/Perl lets an unprivileged database user change sensitive process environment variables such as PATH, which can lead to arbitrary code execution even without OS-level access. Fixed in 12.21, 13.17, 14.14, 15.9, 16.5, and 17.1. CVSS 3.1 8.8, CWE-610.
  • CVE-2024-7348pg_dump TOCTOU privilege escalation. A time-of-check to time-of-use race condition in pg_dump lets an object creator execute arbitrary SQL functions as the user running pg_dump — often a superuser, and often via a scheduled backup. Fixed in 12.20, 13.16, 14.13, 15.8, and 16.4. CVSS 3.1 7.5 (NIST), CWE-367.
  • CVE-2017-7546 — Empty-password authentication bypass. Before 9.2.22 / 9.3.18 / 9.4.13 / 9.5.8 / 9.6.4, an incorrect authentication check allowed a remote attacker to log in to a database account that had an empty password, regardless of the pg_hba.conf method. CVSS 3.0 9.8, CWE-287.

Two of the most useful post-authentication paths are features, not CVEs, and belong on any exposed-PostgreSQL checklist:

  • OS command execution via COPY ... FROM PROGRAM. As a superuser, COPY temp_table FROM PROGRAM 'id' runs the shell command and captures its output into a table — the whole basis of CVE-2019-9193 and the Metasploit module above.
  • File read/write and UDF escalation. Large-object functions lo_import() / lo_export() read and write files with the privileges of the postgres OS account, and a compiled C-language user-defined function loaded through the database runs native code — the technique exploit/linux/postgres/postgres_payload automates via pg_largeobject.

Mitigation

  • Never expose 5432 to the internet. Keep listen_addresses bound to localhost or an internal address, put the database on the app tier or a private subnet, and firewall the port to known database clients only.
  • Fix pg_hba.conf. Remove every trust line for anything but strictly local, throwaway setups; use scram-sha-256 for password authentication (not the legacy md5); and tighten host rules so accounts only connect from the ranges they should — never 0.0.0.0/0.
  • Strong credentials and least-privilege roles. Set a strong postgres superuser password, and give each application its own role scoped to just the database and privileges it needs — no superuser for app connections.
  • Restrict the dangerous privileges. Don’t grant pg_execute_server_program, pg_read_server_files, or pg_write_server_files unless a role truly needs them, and lock down the public schema (revoke CREATE) to close the CVE-2018-1058 search-path class.
  • Require TLS. Configure server certificates and require encrypted connections (hostssl rules, sslmode=verify-full clients) so credentials and query data aren’t sniffable.
  • Patch and monitor. Keep PostgreSQL on a current minor release (the PL/Perl, pg_dump, and empty-password bugs are all fixed upstream), enable log_connections / log_disconnections, and alert on repeated failed logins and new roles.

Real-World Example

In late 2020, Palo Alto Networks’ Unit 42 documented PGMiner, a Linux cryptomining botnet whose entire delivery mechanism was PostgreSQL on port 5432. It scanned the internet for exposed servers, brute-forced the default postgres account, and — once in — abused the COPY ... FROM PROGRAM feature (the disputed CVE-2019-9193) to escalate from database access to operating-system command execution, then pulled down and ran a Monero miner controlled through a Tor-hosted C2. No memory-corruption exploit, no zero-day — just an internet-facing 5432 with a weak password and a superuser that could shell out. It’s a clean illustration of why the two headline PostgreSQL risks — exposure with weak authentication, and superuser command execution — matter so much together.

FAQ

What is port 5432 used for?

Port 5432 is the default TCP port for PostgreSQL database servers. Client applications connect to it to authenticate and run SQL queries. In a secure setup it’s only reachable from the application server or localhost, never the public internet.

Is port 5432 dangerous?

It is when it’s exposed. A PostgreSQL server on the internet is constantly scanned and brute-forced, and a trust rule or a weak postgres password gives an attacker every database on the server — often followed by OS command execution on the host via COPY ... FROM PROGRAM. Port 5432 should be firewalled to trusted clients and never left open to the world.

What is the difference between port 5432 and port 3306?

Both are default database ports that should stay off the public internet. Port 5432 is PostgreSQL; port 3306 is MySQL and MariaDB. They use different wire protocols and clients (psql vs mysql), but the exposure risks — weak or default credentials, over-broad access rules, and post-authentication paths to the host — are very similar.

How do I secure or close port 5432?

Bind PostgreSQL to localhost or an internal address, firewall 5432 to known database clients, remove trust rules and use scram-sha-256 in pg_hba.conf, set a strong postgres password, give each app a least-privilege role, restrict pg_execute_server_program and server-file privileges, require TLS, and patch. If nothing external needs the database, make sure the port isn’t reachable off-host and confirm with a rescan.

TL;DR

  • Service: PostgreSQL relational database (postgres backend)
  • Default port: 5432/TCP
  • Biggest risk: internet exposure with trust auth or a weak postgres password, escalating to OS command execution via COPY ... FROM PROGRAM
  • Mitigation: bind to localhost/internal, firewall to trusted clients, fix pg_hba.conf (no trust, use scram-sha-256), least-privilege roles, require TLS, patch