Medium risk Ports 3306 · 5432 · 27017 · 6379
Database port open to the internet: what it means and how to fix it
Short answer: your database, where customer records, orders or passwords usually live, accepts connections from anywhere on the internet. Bots scan for exposed databases constantly, guess passwords, and in some well-known waves have copied the data, wiped it, and left a ransom note.
The fix: make the database listen only on the server itself or your private network, block the port at the firewall, and connect remotely through an SSH tunnel or VPN instead.
Which port is which
| Port | Database | Commonly used by |
|---|---|---|
3306 | MySQL / MariaDB | WordPress, WooCommerce, most PHP websites |
5432 | PostgreSQL | Custom web apps, Django, Rails, many SaaS tools |
27017 | MongoDB | Node.js apps, analytics, newer web apps |
6379 | Redis | Caching, sessions, job queues |
Others follow the same rules: Microsoft SQL Server (1433), Elasticsearch (9200) and CouchDB (5984).
Why it's dangerous
- Mass ransom attacks. In 2017, automated attacks wiped tens of thousands of internet-facing MongoDB databases and left ransom notes demanding Bitcoin. The same thing has happened since to Elasticsearch, MySQL and PostgreSQL servers. Paying rarely gets the data back.
- Password guessing. Database logins don't usually lock after failed attempts, so bots can guess for as long as they like. A weak or default password, or none, is found quickly.
- Redis is a special case. Older or misconfigured Redis servers have no password at all. Attackers use exposed Redis to install cryptominers, and in some setups to write their own SSH key onto the server and take it over.
- Every database bug becomes reachable. If the database software has an unpatched flaw, anyone on the internet can try it.
- It's a reportable breach. If customer data leaks from an exposed database, privacy laws in many places require you to notify the people affected.
- 3306 MySQL Exposed directly to the network increases data-breach risk Medium
- 6379 Redis Often deployed with no authentication Medium
How to confirm it
- From outside your network, run a free FreshScanSentry Basic Scan, or use Nmap from another connection:
nmap -p 3306,5432,27017,6379 -sV your-server - On the server, see which address each database listens on:
sudo ss -tlnp | grep -E ':(3306|5432|27017|6379)\b'127.0.0.1or[::1]means local only, which is good.0.0.0.0,*or[::]means every network interface, so it's only as safe as your firewall. - In the cloud, check the database's network settings. On AWS RDS, look at "Publicly accessible" and the security group. On Azure, Google Cloud and DigitalOcean managed databases, look at "public access" or the trusted-sources list. Any rule allowing
0.0.0.0/0means the whole internet.
Only scan addresses you own or have written permission to test.
How to fix it
1. Make the database listen locally
If the website and the database are on the same server, which is typical for WordPress, the database never needs to accept outside connections.
MySQL / MariaDB. In /etc/mysql/mysql.conf.d/mysqld.cnf (MariaDB: /etc/mysql/mariadb.conf.d/50-server.cnf):
bind-address = 127.0.0.1
PostgreSQL. In postgresql.conf:
listen_addresses = 'localhost'
Also remove any line in pg_hba.conf that allows 0.0.0.0/0 or ::/0.
MongoDB. In /etc/mongod.conf:
net:
bindIp: 127.0.0.1
security:
authorization: enabled
Redis. In redis.conf:
bind 127.0.0.1 -::1
protected-mode yes
requirepass use-a-long-random-password-here
Restart the database after each change, and check that the website still works.
2. If another server needs it: allow only that server
When the app runs on a different machine, bind the database to the private network address, not the public one. Then allow the port in the firewall only from the app server's IP address. In the cloud, use a security group or firewall rule that allows the app server only, never 0.0.0.0/0.
# Example with ufw: allow MySQL only from the app server
sudo ufw allow from 10.0.0.5 to any port 3306 proto tcp
sudo ufw deny 3306/tcp
3. Watch out for Docker
Publishing a database container with -p 3306:3306 opens it on every interface, and Docker's own firewall rules bypass ufw. A port you thought was blocked may be wide open. Publish to localhost only, or don't publish at all and let containers talk over a private Docker network:
# docker run
-p 127.0.0.1:3306:3306
# docker-compose.yml
ports:
- "127.0.0.1:3306:3306"
4. Connect remotely through a tunnel, not an open port
For your own access from a laptop with a tool like MySQL Workbench, pgAdmin or MongoDB Compass, use an SSH tunnel:
ssh -L 3306:127.0.0.1:3306 you@your-server
Then point the tool at 127.0.0.1:3306 on your own computer. Most database tools also have a built-in "connect over SSH" option. A VPN works too.
5. Tighten accounts and update
- Give every database account a long, unique password, and remove accounts you don't use.
- In MySQL, look for accounts allowed from anywhere:
SELECT user, host FROM mysql.user;A host of%means any address. Change it tolocalhostor the app server's IP. - Give the website's database user only the permissions it needs, not full admin.
- Install database security updates, and keep backups stored somewhere else, so a wiped database can be restored.
6. Re-scan to confirm
Run another external scan. The database ports should no longer appear.
If you think it's already been hit
Warning signs include a new table or collection with a name like README, WARNING or RECOVER_YOUR_DATA, missing data, unknown database users, unfamiliar keys in Redis, or the server's CPU running at 100% (a sign of a cryptominer). Take the database off the internet straight away. Don't pay, because these attacks often delete the data without keeping a copy. Restore from a backup, and talk to an incident response provider about whether customer data was taken.
Common questions
Our database has a strong password. Is that enough?
It helps, but it doesn't stop attacks on bugs in the database software, and it does nothing if an app config file containing the password leaks. A database that isn't reachable can't be attacked from the internet at all.
Why does FreshScanSentry rate this Medium and not High?
The scan can see that the port is open, but it doesn't try to log in, so it can't tell whether the database has a strong password, a weak one, or none. Treat it as urgent if you aren't sure.
Our hosting company manages the database.
Send them the scan result and ask them to restrict access to your website's server only. Most managed hosts can do this quickly.
Sources: MySQL: bind_address · PostgreSQL: connection settings · MongoDB security checklist · Redis security · Docker and firewalls