Skip to main content
Exposed ServiceHigh

Exposed Database Server (PostgreSQL/MySQL)

An exposed database server is a PostgreSQL (TCP 5432) or MySQL/MariaDB (TCP 3306) instance whose listener is reachable from the public internet, letting anyone attempt authentication directly against the data store. Because the protocol handshake leaks the product and version before login, attackers can fingerprint, brute force, and ultimately read or wipe the entire database.

A database is the one asset that, when it falls, takes everything with it: customer records, credentials, billing data, and the application's source of truth. Yet a routine misstep, a security group left at 0.0.0.0/0, a bind-address widened during debugging, a container port published to the host, quietly turns an internal data store into a public endpoint. The listener does not need a vulnerability to be dangerous; the mere fact that strangers can speak the wire protocol to your database is the exposure.

Reviewed by Ameya Lambat

Security Research Contributor, Legba

Reviewed 2026-05-28 · Updated 2026-05-28

What it is

PostgreSQL listens on TCP 5432 and MySQL/MariaDB on TCP 3306 by default. These are wire protocols designed for trusted, low-latency networks, not the open internet. An exposed database server is any instance whose listener accepts TCP connections from arbitrary internet hosts, regardless of whether authentication is eventually required. The exposure typically arises from a permissive cloud security group, a firewall rule allowing all sources, MySQL's bind-address set to 0.0.0.0, a PostgreSQL listen_addresses of '*' paired with a permissive pg_hba.conf, or a container that publishes the port to the host's public interface. Once reachable, the server begins its protocol handshake with any caller, which is enough to enumerate it and start attacking credentials.

When a database is internet-reachable, the worst-case outcome is not slow data leakage, it is total loss in a single automated pass. Border0 researchers documented a ransomware bot that, within hours of a fresh PostgreSQL or MySQL instance being exposed, brute-forced its way in, snapshotted a fragment of the data, dropped every database, and left a ransom note demanding cryptocurrency, with no real recovery for victims who paid. With hundreds of thousands of PostgreSQL servers and millions of MySQL servers indexed as internet-facing, your instance is found by mass scanners in minutes, not weeks. The stakes are concrete: regulated personal data exfiltration triggering breach-notification duties, full database destruction halting the business, and lateral movement using credentials and secrets harvested from the very tables you were trying to protect.

At a glance

Typeexposed-database-server
Ports5432, 3306
Protocolstcp
Seen onPostgreSQL, MySQL, MariaDB, Amazon RDS, Aurora, Cloud SQL, Azure Database for MySQL/PostgreSQL, Docker, Kubernetes
SeverityHigh
Updated2026-05-28

How attackers find and exploit it

  • Run internet-wide scans for open TCP 5432 and 3306 using Shodan, Censys, or masscan, harvesting every host whose listener completes a TCP handshake.
  • Fingerprint each candidate by reading the protocol greeting: MySQL sends an initial handshake packet exposing the server version string (e.g. 8.0.36), while PostgreSQL responds to a startup message and reveals the negotiated SCRAM/MD5 auth mechanism and version via error and parameter-status frames.
  • Test for missing or trivial authentication, attempting passwordless logins, default accounts such as 'postgres' or 'root', and well-known weak credentials before any heavy effort.
  • Brute-force and password-spray valid usernames against the listener using tools like Hydra, Medusa, or NSE scripts, exploiting the absence of native rate limiting or lockout on these protocols.
  • Once authenticated, enumerate schemas, dump tables (SELECT or mysqldump/pg_dump), and escalate: abuse PostgreSQL COPY ... PROGRAM or untrusted procedural languages, or MySQL FILE privileges and UDFs, to achieve command execution on the host.
  • Stage impact by exfiltrating a data sample, then issuing destructive DROP DATABASE or bulk DELETE statements and creating a ransom table (e.g. RECOVER_YOUR_DATA) demanding payment.

How to detect it on your surface

  • Inventory every cloud security group, network ACL, and host firewall rule that permits inbound 5432 or 3306, flagging any source of 0.0.0.0/0 or ::/0.
  • Scan your own public IP ranges and elastic/load-balancer addresses from an external vantage point for open 5432 and 3306, since internal scans miss what the internet actually sees.
  • Audit database configuration: PostgreSQL listen_addresses and pg_hba.conf entries, and MySQL/MariaDB bind-address, confirming they bind to localhost or a private interface rather than 0.0.0.0.
  • Review container and orchestrator manifests for published ports (Docker -p 5432:5432, Kubernetes Services of type LoadBalancer/NodePort) that route database traffic to a public interface.
  • Search asset-management and CMDB records for managed instances (RDS, Cloud SQL, Azure Database) whose 'publicly accessible' flag is enabled.

Detection signals

  • MySQL initial handshake packet containing a server version banner (for example '8.0.36' or '5.7.44') and a protocol-version byte of 0x0a returned immediately on connect.
  • PostgreSQL responds to a startup packet with an authentication request frame ('R') indicating SCRAM-SHA-256, MD5, or, dangerously, 'trust'/no-auth, plus ParameterStatus frames disclosing server_version.
  • A clean TCP three-way handshake completing on 5432 or 3306 from an external scanner, confirming the listener is reachable rather than filtered.
  • PostgreSQL FATAL errors such as 'no pg_hba.conf entry for host' or 'password authentication failed for user', which confirm a live, internet-reachable server even when login fails.
  • Spikes of short-lived connections and authentication failures in pg_stat_activity / the PostgreSQL log, or MySQL aborted_connects and access-denied entries, indicating active brute-force traffic.

Validate before you report

  • Confirm reachability from outside your perimeter by completing a TCP connection to the host on 5432/3306 from an external network, distinguishing a truly open listener from a filtered or internal-only one.
  • Send the protocol handshake (a PostgreSQL startup message or read the MySQL greeting) and capture the version banner and offered authentication method as evidence the service is a real, identifiable database.
  • Probe for weak authentication safely with a single non-destructive login attempt using a default or empty credential, recording whether the server returns an auth challenge, a clear rejection, or, critically, a successful 'trust' connection, never running destructive queries.
  • Cross-reference the source-of-truth network policy: tie the observed open port back to the specific security-group rule, firewall entry, or bind-address setting that permits it, proving the path is intentional and not a transient artifact.
  • Capture and timestamp the evidence (banner, auth method, reachable source range) so the finding is a confirmed true positive an owner can act on, rather than an unverified port hit.

What looks like this but isn't

  • A port that appears open in a passive dataset but is actually filtered or behind a deny rule, verify with a live external handshake before reporting, as stale Shodan/Censys records can lag firewall changes.
  • A bastion, VPN concentrator, or SSH-tunnel endpoint that proxies database traffic only after authenticating at a separate layer, the database listener itself may be private even though the front door looks port-adjacent.
  • A non-production decoy or honeypot intentionally exposing 5432/3306 to capture attacker behavior, which should be excluded from remediation and tracked separately.

Remediation

  • Immediately remove the public path: restrict the cloud security group, network ACL, or firewall so inbound 5432/3306 is allowed only from explicit trusted CIDRs or private subnets, never 0.0.0.0/0.
  • Bind the listener to a private interface, set MySQL/MariaDB bind-address to a private or loopback address and PostgreSQL listen_addresses to specific internal IPs, then restart the service.
  • Tighten host-based authentication: in PostgreSQL pg_hba.conf require scram-sha-256 over hostssl from defined hosts and eliminate any 'trust' lines; in MySQL drop anonymous and wildcard-host accounts and scope GRANTs to specific hosts.
  • Place all database access behind a VPN, bastion, or cloud private link so connections originate from an authenticated network boundary rather than the open internet.
  • Rotate all database credentials and any application secrets that may have transited the exposed listener, and enforce strong, unique passwords plus least-privilege roles.
  • Enable and require TLS for client connections, then enable verbose authentication logging and audit recent connections and queries to rule out prior compromise before closing the finding.

Operational checklist

  • Maintain a default-deny ingress posture for database ports, with exceptions granted only to named private sources and reviewed on a schedule.
  • Continuously scan your own external IP space for open 5432/3306 and alert on any new database listener appearing on the internet.
  • Disable the 'publicly accessible' option on all managed instances (RDS, Cloud SQL, Azure Database) and enforce it through infrastructure-as-code policy and CI guardrails.
  • Require TLS, strong SCRAM/native authentication, and per-host GRANTs as a baseline standard for every database, validated at provisioning time.
  • Monitor authentication-failure and connection-rate metrics (pg_stat_activity, MySQL aborted_connects) and alert on brute-force patterns.
  • Keep PostgreSQL and MySQL patched to supported minor versions so a reachable banner does not also reveal an exploitable, end-of-life build.

What to do next

An internet-reachable PostgreSQL or MySQL listener is found by automated scanners within minutes and can be brute-forced and wiped in a single pass, so the first action is the highest leverage: confirm whether your database ports answer from outside your perimeter, and if they do, cut the public path today by scoping the security group and binding to a private interface. Pair that with a credential rotation and a log review for prior access. Don't wait for a ransom table to appear, validate the exposure now and close it.

Methodology

Each finding-type guide is built from Legba Recon's real detection and validation logic, reviewed by a named security contributor, and cited against primary sources such as OWASP, CISA, NIST, and MITRE. We update pages when the underlying guidance changes. See our contributors and company.

FAQs.

References.

Weakness references (CWE)

Keep exploring

Your agent needs its Legba.

Read the docs