critical10 min readLast updated May 27, 2026

Exposed Database Ports: A Critical Security Finding You Must Fix Now

Database ports like MySQL 3306, PostgreSQL 5432, MongoDB 27017, and Redis 6379 exposed to the internet are a critical risk. Learn how to detect and secure them.

Why exposed database ports are a critical finding

A database port accessible from the internet means anyone in the world can attempt to connect to your database. This is one of the most severe findings in attack surface management because the consequences are immediate and devastating:

  • Direct access to all your data -- customer records, credentials, financial data, intellectual property
  • No web application firewall in between -- the attacker connects directly to the database engine
  • Many databases have weak or no authentication by default -- Redis and older MongoDB versions require no password out of the box
  • Automated scanners find them in minutes -- tools like Shodan, Censys, and Masscan continuously index every open port on the internet

This is not theoretical. Thousands of databases are compromised every month because they were left exposed.

Which ports and services are at risk?

Database Default Port Notes
MySQL / MariaDB 3306 Most common exposed database
PostgreSQL 5432 Strong auth, but exposure is still a risk
MongoDB 27017 Historically no auth by default
Redis 6379 No authentication by default
Elasticsearch 9200 / 9300 REST API with no auth by default
Microsoft SQL Server 1433 Common target for brute force
CouchDB 5984 HTTP API, often no auth
Cassandra 9042 No auth by default
Memcached 11211 No auth, used in DDoS amplification

Real-world consequences

Data theft

Attackers connect, dump the database, and sell the data or use it for identity theft. This has happened to companies of every size.

Ransomware (database ransom)

Attackers connect to an exposed MongoDB or Elasticsearch instance, delete all data, and leave a ransom note: "Send 0.5 BTC to get your data back." This became so common it got its own name -- "meow attacks" deleted thousands of databases in 2020.

Cryptomining

Exposed Redis instances are frequently exploited to inject cron jobs that download cryptocurrency miners. The attacker gains free compute at your expense.

Botnet recruitment

Attackers use exposed databases to stage malware or use the server as part of a botnet for DDoS attacks.

Compliance violations

Exposed database ports are an automatic fail for PCI DSS, SOC 2, ISO 27001, and NIS2 audits. They demonstrate a fundamental lack of network segmentation.

How to check if your databases are exposed

Using nmap

# Check common database ports on your public IP
nmap -p 3306,5432,27017,6379,9200,9300,1433,5984,9042,11211 your-public-ip

# Scan an entire range
nmap -p 3306,5432,27017,6379,9200,9300,1433,5984,9042,11211 --open your-ip-range/24

Any port showing open is accessible from the internet.

Using netcat (quick check)

# Test if MySQL is reachable
nc -zv your-public-ip 3306

# Test if Redis is reachable
nc -zv your-public-ip 6379

From the server itself

Check what interfaces each database is listening on:

# Show all listening ports
sudo ss -tlnp | grep -E '3306|5432|27017|6379|9200|1433'

If you see 0.0.0.0:PORT or :::PORT, the database is listening on all interfaces -- including the public one.

Using Shodan

Search for your IP on Shodan to see what an attacker sees. You can also set up alerts for your IP ranges.

How to fix: General principles

The fix has three layers, and you should apply all of them:

  1. Bind to localhost -- configure the database to only listen on 127.0.0.1
  2. Firewall rules -- block database ports from the internet at the network level
  3. Authentication -- ensure strong passwords are set (defence in depth)

Specific fixes by database

MySQL / MariaDB

Edit the MySQL configuration file (/etc/mysql/mysql.conf.d/mysqld.cnf or /etc/my.cnf):

[mysqld]
bind-address = 127.0.0.1

Restart MySQL:

sudo systemctl restart mysql

If other servers need to connect (e.g., an application server), bind to the private IP and use firewall rules:

# Allow MySQL only from your application server's private IP
sudo ufw allow from 10.0.1.5 to any port 3306 proto tcp
sudo ufw deny 3306

PostgreSQL

Edit postgresql.conf:

listen_addresses = 'localhost'

And pg_hba.conf to restrict which hosts can authenticate:

# Only allow local connections
local   all   all                     peer
host    all   all   127.0.0.1/32      scram-sha-256
host    all   all   ::1/128           scram-sha-256

Restart PostgreSQL:

sudo systemctl restart postgresql

MongoDB

Edit /etc/mongod.conf:

net:
  port: 27017
  bindIp: 127.0.0.1

security:
  authorization: enabled

Enable authentication and create an admin user:

// Connect to mongo shell
use admin
db.createUser({
  user: "admin",
  pwd: "a-very-strong-password-here",
  roles: [ { role: "root", db: "admin" } ]
})

Restart MongoDB:

sudo systemctl restart mongod

Redis

Edit /etc/redis/redis.conf:

# Bind to localhost only
bind 127.0.0.1 ::1

# Require a password
requirepass your-very-strong-password-here

# Disable dangerous commands
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
rename-command DEBUG ""

Restart Redis:

sudo systemctl restart redis

Elasticsearch

Edit /etc/elasticsearch/elasticsearch.yml:

network.host: 127.0.0.1
xpack.security.enabled: true

Set up passwords:

sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

Restart Elasticsearch:

sudo systemctl restart elasticsearch

Microsoft SQL Server

Use SQL Server Configuration Manager to change the IP addresses MSSQL listens on. Disable listening on public interfaces.

Additionally, ensure:

  • sa account is disabled or has a very strong password
  • Windows Authentication mode is preferred over SQL Server Authentication
  • Firewall rules restrict port 1433 to known application servers only

Use SSH tunnels for remote access

If you need to access a database from your local machine for administration, use an SSH tunnel instead of opening the port:

# Create an SSH tunnel to MySQL
ssh -L 3306:localhost:3306 user@your-server

# Then connect locally
mysql -h 127.0.0.1 -u dbuser -p

This keeps the database port closed to the internet while giving you secure access through the encrypted SSH connection. For more on securing SSH itself, see our guide on SSH access security.

Firewall rules as defence in depth

Even after binding to localhost, add firewall rules as a second layer:

# Block all database ports from the internet
sudo ufw deny 3306
sudo ufw deny 5432
sudo ufw deny 27017
sudo ufw deny 6379
sudo ufw deny 9200
sudo ufw deny 9300
sudo ufw deny 1433

In cloud environments, configure security groups to deny inbound traffic on database ports from 0.0.0.0/0. Only allow connections from specific private IPs or subnets.

Post-fix verification

After applying fixes, verify from outside your network:

# Each of these should show "filtered" or "closed"
nmap -p 3306,5432,27017,6379,9200,1433 your-public-ip

Also check with Shodan -- it may take a few days for their cache to update, but the ports should disappear from your listing.

For a broader view of your exposed services, review our guide on open ports security which covers other commonly exposed and dangerous ports.

How SurfaceScan helps

SurfaceScan scans your entire external attack surface for exposed database ports on every scan cycle. It checks not just the default ports but also common alternative ports where databases are sometimes configured. Exposed database findings are flagged as critical severity because of the immediate data breach risk. Each finding shows the specific port, the database service detected, and step-by-step remediation guidance. SurfaceScan also monitors for changes -- if a database port appears after a deployment or configuration change, you are alerted before an attacker finds it.

Related articles