Exposed database ports: MySQL, PostgreSQL, MongoDB, Redis and Elasticsearch
A database port is exposed when anyone on the internet can open a connection to it. Your application needs to reach the database; a random computer in another country does not. Yet a single firewall rule, a changed config line or a cloud default can make MySQL, PostgreSQL, MongoDB, Redis or Elasticsearch answer the whole internet.
An open port is not automatically a breach. If authentication is strong and the software is up to date, the attacker still has to get past it. But an open port turns your database into something anyone can probe, guess passwords against and test for known vulnerabilities. Closing it removes the whole category of risk.
This article lists the default ports, shows how to check from outside and explains how to close them properly.
The default ports to know
These are the default ports from each vendor's documentation:
- MySQL: 3306 for the classic protocol, 33060 for X Protocol.
- PostgreSQL: 5432.
- MongoDB: 27017 for
mongodandmongos. - Redis: 6379, as set in the default
redis.conf. - Elasticsearch: HTTP API on the first available port in the 9200 to 9300 range, usually 9200, and the transport layer on 9300 to 9400.
Services can run on other ports, so treat this list as a starting point, not a complete scan.
How databases end up on the internet
Most of these products are safer by default than they used to be:
- PostgreSQL's
listen_addressesdefaults tolocalhost. - MongoDB binds to localhost by default.
- Redis, since version 3.2.0, runs in protected mode when it listens on all interfaces without a password, and then answers only local clients.
- Elasticsearch 8.0 and later enables security automatically on first start.
So exposure usually comes from a deliberate change that was meant to be temporary:
- someone set
bind-address = 0.0.0.0,listen_addresses = '*'orbindIpAllso a developer could connect from home, - protected mode or security was switched off to "make it work",
- a cloud security group or firewall rule allows the port from
0.0.0.0/0, - a Docker
-p 6379:6379publishes the port on every interface of the host, - an old test or staging server with its own database was never shut down.
The Redis documentation is direct about the risk: Redis is designed for trusted clients in trusted environments, and an exposed instance can lose its whole data set to a single FLUSHALL command.
How to check from outside
The check must run from outside your network, otherwise you only test the internal path. Use a machine on a different connection (a cloud VM, a phone hotspot) and test only IP addresses you own:
for port in 3306 5432 27017 6379 9200 9300; do
nc -z -w 3 203.0.113.10 $port && echo "$port open" || echo "$port closed"
done
On the server itself, see which addresses each service listens on:
sudo ss -tlnp | grep -E ':(3306|5432|27017|6379|9200|9300)\b'
127.0.0.1:5432 or a private address is what you want. 0.0.0.0:5432 or [::]:5432 means the service listens on every interface, and only a firewall stands between it and the internet.
Internet scanners also index open ports for every public IP address. For a quick look at what they have recorded for one of your addresses, Shodan offers a simple lookup at https://internetdb.shodan.io/<your-ip>.
How to close it properly
Use 2 layers, so that one mistake does not expose the database again:
- Bind to private interfaces only.
bind-address = 127.0.0.1(MySQL),listen_addresses = 'localhost'or a private IP (PostgreSQL),net.bindIp(MongoDB),bind 127.0.0.1withprotected-mode yes(Redis),network.hoston a private address (Elasticsearch). - Restrict at the network level. The firewall or cloud security group should allow the database port only from your application servers.
- Remote access through a tunnel. Developers connect over SSH tunnels or a VPN, never through an open port.
- Require authentication everywhere, even on internal networks: users with least privilege, long passwords, and TLS for connections that leave a single host.
- Keep the software updated, so that if a port is ever exposed by mistake, it does not also run a version with known vulnerabilities.
If a database was exposed with weak or no authentication, treat its data as possibly copied: rotate credentials, review logs and consider your notification duties.
A short checklist
- List every public IP address your company uses, including old servers.
- Test the common database ports from outside.
- Make sure each database listens only on localhost or a private address.
- Allow database ports in the firewall only from application servers.
- Recheck after every migration, new server or Docker change.
Open services rarely appear alone. They often sit on the same forgotten staging servers that also leak .env and backup files.
How Datahorses helps
Datahorses watches your company from the outside every day and shows which services an attacker can see on your public addresses, including database ports and remote access such as RDP or SSH, together with known vulnerabilities for the versions they reveal. We do not enter your systems and need no access. Each finding comes with exact steps for your developer, as described in what happens when we find something. The example dashboard shows what such a report looks like.
More articles
Attack surface monitoring vs EDR and XDR: complement, not competitor
EDR and XDR look inward at devices, logins and processes. External attack surface monitoring looks at your company from the internet. Here is why you want both views.
Gmail and Yahoo sender requirements: what changed in 2024 and what to check
Since February 2024 Gmail and Yahoo expect authenticated, aligned mail and easy unsubscribes from bulk senders. Here is what the rules say and how to check your own domain.
PHP2Shell: which PHP versions are fixed and how to check yours
The PHP project fixed 2 critical flaws on 21 October 2026. Here is which versions contain the fix, how to see what your server reports and what to ask your host.