In this guide · 7 sections
Short answer
A database should listen only on localhost or a private network, require a password or key for every connection, and sit behind a firewall that blocks its port from the internet. Test from outside, not from the server itself. The PDPC has fined Singapore firms over MongoDB databases without passwords.
How databases end up exposed
Very few businesses decide to put their database on the internet. It happens through small changes that each seemed harmless at the time.
- Changing the bind address to fix a connection problem. A developer sets it to 0.0.0.0 so another server or their laptop can connect, and never changes it back.
- Publishing a Docker port. Mapping the database container's port to the host makes it reachable on the server's public IP.
- Test and staging servers. Copies of production data on a cheap VPS with default settings and no firewall.
- No authentication. Access control left off because the database was "only local" when it was set up.
- Cloud firewall rules opened to everyone. A security group or firewall rule allowing the database port from any address.
What MongoDB, MySQL and Elasticsearch do by default
Defaults have improved over the years, but they differ by product, and many servers run older versions or packaged configs.
| Database | Default network binding | What to check |
|---|---|---|
| MongoDB | Binds to localhost by default, per MongoDB's IP binding docs | net.bindIp, and that access control (authorization) is enabled |
| MySQL 8.4 | bind_address defaults to *, all IPv4 and IPv6 interfaces, per the MySQL reference manual | bind_address in the server config; distribution packages may set 127.0.0.1 |
| Elasticsearch | network.host defaults to _local_; security auto-configuration adds http.host: 0.0.0.0 for HTTP | network.host and http.host in elasticsearch.yml, and that security is on |
Elastic's networking settings page puts it plainly: never expose an unprotected node to the public internet, because anyone could download, modify or delete the data. MongoDB's security checklist starts with enabling access control and enforcing authentication before going to production.
How to check whether your database is exposed
Checking from the server itself proves nothing, because the database will always answer locally. Test from outside.
List what is listening on the server
On Linux, run ss -tlnp and note any database process bound to 0.0.0.0, :: or the public IP rather than 127.0.0.1.
Check the cloud and server firewalls
Look at the provider's firewall or security group and at ufw or iptables. Any rule allowing the database port from 0.0.0.0/0 is a red flag.
Check Docker port mappings
Run docker ps and look for database ports mapped to 0.0.0.0. Bind them to 127.0.0.1 or remove the mapping and use a private Docker network.
Test from an outside network
From a phone hotspot or another provider, try connecting to the server's public IP on the database port. It should time out or be refused.
Look at an external scan of your IP
Services such as Shodan's InternetDB show open ports seen from the internet for an IP address. Check your own IPs only.
Our guide to checking open ports and server firewalls goes through each provider's firewall settings in more detail.
What the PDPC said in exposed MongoDB cases
Two published PDPC decisions involve MongoDB databases without proper access control. Both found breaches of the Protection Obligation in section 24 of the PDPA.
- DS Human Resource Pte. Ltd. [2019] SGPDPC 16 (13 June 2019). The company stored job applicants' personal data, including NRIC images and bank details for about 2,100 people, in MongoDB on AWS. The decision found the default settings it used allowed remote connections through the internet and the database had no password protection. A hacker deleted the data and demanded bitcoin; there was no backup. Penalty: S$33,000.
- RedMart Limited [2022] SGPDPC 8 (28 October 2022). Customer data was in a MongoDB database that was not encrypted and had no password authentication; attackers reached it using an exposed cloud access key. The decision imposed a S$72,000 penalty.
The DS Human Resource decision opens with a line every small business using open-source software should read: the case "illustrates the risks to companies in using default settings of open source software without any assessment of the security features". If an exposed database held personal data, our data breach notification guide explains when you must notify the PDPC and affected individuals.
Fixing an exposed database, in order
If you find a database reachable from the internet, close the exposure first, then work out whether anyone used it.
Exposed database response
For remote access by developers, use an SSH tunnel or a VPN instead of opening the database port. For a managed database service, restrict access to your app server's private network or IP addresses.
Do it yourself or get help?
If you run one server and know the stack, the checks above take less than an hour and are worth doing every quarter. Get help if you find an exposure, run Docker with published ports, or inherited a server nobody fully understands.
IT Sorted is a Singapore-based team of developers with over 10 years of experience. Our Software & Server Protection Setup (S$590) sets up the firewall with only the ports you need, brute-force protection, automatic security updates, daily malware scans, encrypted off-site backups with a tested restore and a written runbook, on tools in your own account. A Security Health Check (S$290) is a written external review of your domain, website and email with a fix list. Cleaning up a server that is already compromised is quoted separately, and penetration testing needs a CSA-licensed provider.
Frequently asked questions
Current MongoDB versions bind to localhost by default, according to MongoDB's documentation, so they are not reachable from other machines until someone changes the bind address. Problems start when bindIp is set to 0.0.0.0 or the port is published through Docker without access control. MongoDB's security checklist says to enable authentication before production.
The MySQL 8.4 reference manual lists the default bind_address as *, meaning all IPv4 and IPv6 interfaces. Some Linux distribution packages ship a config file that sets it to 127.0.0.1 instead. Check the actual value on your server and make sure the firewall blocks the MySQL port from the internet either way.
Docker's documentation explains that published container ports are routed before traffic reaches the chains ufw uses, so ufw rules are effectively ignored for those ports. Bind published ports to 127.0.0.1, use private Docker networks between containers, or apply rules in the DOCKER-USER chain or your cloud firewall.
Test from outside the server. Try connecting to the public IP and database port from a different network such as a phone hotspot, and look at external scan data for your own IP address. Also review the cloud firewall, server firewall and any Docker port mappings, because any one of them can open the port.
In DS Human Resource (2019), the PDPC imposed a S$33,000 penalty after a MongoDB database left on default settings, without password protection, was accessed and wiped. In RedMart (2022), it imposed S$72,000 over a MongoDB database without encryption or password authentication. Both were breaches of the PDPA's Protection Obligation.