MongoDB Security Hardening in Practice: Unauthorized Access Prevention and Data Encryption Configuration Guide
MongoDB unauthorized access is a common path to database compromise. This article starts from the mechanics and gives a complete plan: enable authentication, bind internal addresses, enable TLS, and configure least-privilege accounts, with ready-to-run mongod.conf and verification commands.
Applicable Scenarios
MongoDB security hardening applies to: instances exposed on the public internet that allow unauthorized access; authentication left disabled after growth, so anyone can connect via mongo shell and read or tamper with data; MLPS 2.0 or financial-industry compliance that requires encryption and audit of the database access path. This article starts from MongoDB unauthorized-access mechanics and delivers a complete plan: enable authentication, configure access control, enable TLS encryption, and apply a security baseline.
Prerequisites
- A server with MongoDB installed (MongoDB 6.0/7.0 Community Edition in this article)
- Read/write access to `/etc/mongod.conf`
- SSH access to the server, with a firewall already configured (iptables or a cloud security group)
How It Works
MongoDB unauthorized access is authentication left off. Default config does not verify client identity. Any IP that can reach port 27017 connects with admin privileges. `db.adminCommand({listDatabases:1})` enumerates every database, then dump or ransomware follows. Authentication uses SCRAM-SHA-256: the client presents username and password; the server verifies the credential. Roles control permission granularity. Least privilege requires application accounts to hold only the read/write they need on their own databases. If data crosses the public internet, enable TLS so passwords and data are not intercepted.
Procedure
1. Create an admin account
# Start temporarily without authentication, or connect directly with the local shell
mongosh --port 27017
# Switch to the admin database and create a superuser
use admin
db.createUser({
user: "admin",
pwd: passwordPrompt(), # Interactively enter a strong password
roles: [{ role: "root", db: "admin" }]
})
Key parameter: `roles: "root"` grants admin rights on all databases. Use only for bootstrap. Switch to restricted roles such as `readWrite` in production.
2. Enable authentication and bind internal addresses
# Edit /etc/mongod.conf
security:
authorization: enabled # Enable authentication
net:
port: 27017
bindIp: 127.0.0.1,192.168.1.10 # Bind only localhost and the internal IP; do not use 0.0.0.0
# Restart to apply
sudo systemctl restart mongod
Key parameters: never set `bindIp` to 0.0.0.0 — that exposes the database on the public internet. `authorization: enabled` is the switch that stops unauthorized access.
3. Verify unauthorized access is blocked
# Direct connection without credentials should return an authentication error
mongosh --host 192.168.1.10 --port 27017
# Output: MongoServerError: Unauthorized
# Log in successfully with username and password
mongosh --host 192.168.1.10 --port 27017 -u admin -p --authenticationDatabase admin
4. Enable TLS encryption
# Generate a self-signed certificate (use a CA-issued certificate in production)
openssl req -newkey rsa:2048 -nodes -keyout mongodb.key -x509 -days 365 -out mongodb.crt
cat mongodb.key mongodb.crt > mongodb.pem
# Update mongod.conf
net:
tls:
mode: requireTLS
certificateKeyFile: /etc/mongodb.pem
sudo systemctl restart mongod
# Encrypted client connection
mongosh "mongodb://192.168.1.10:27017/admin?tls=true" -u admin -p
5. Security baseline hardening
# Disable the HTTP interface (legacy Web admin port; already removed by default)
# Allow access to port 27017 only from the internal network via iptables
sudo iptables -A INPUT -p tcp --dport 27017 -s 192.168.1.0/24 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 27017 -j DROP
# Back up regularly and encrypt backups
dump --out /backup/mongo_$(date +%F) --authenticationDatabase admin -u admin -p
Configuration Verification
# 1. Check that authentication is in effect: a connection without credentials should be rejected
mongosh --host 127.0.0.1 --port 27017 --eval "db.runCommand({connectionStatus:1})"
# 2. Check listen addresses; 0.0.0.0 should not appear
sudo ss -tlnp | grep 27017
# 3. Verify least privilege: a write from a read-only account should be rejected
mongosh -u readonly -p --authenticationDatabase appdb --eval "db.users.insert({x:1})"
# Output: MongoServerError: not authorized on appdb to execute command
FAQ
Q1: After enabling authentication, the application connection returns Unauthorized. How to handle it?
Confirm the connection string includes `authSource` (authentication database), e.g. `mongodb://user:pass@host:27017/appdb?authSource=admin`. Check which database the account belongs to and which roles it has. If the account was created in admin, `authSource` must be admin. Strip stray spaces from username and password.
Q2: After enabling TLS, old clients cannot connect. What to do?
TLS mode `requireTLS` forces encryption on every connection. Upgrade old drivers to a TLS-capable version, or append `?tls=true&tlsAllowInvalidCertificates=true` to the connection string (test only; production should use a trusted CA certificate). If the app cannot change immediately, use `preferTLS` as a stopgap, then switch to mandatory encryption.
Summary
Unauthorized access is one of the most common MongoDB compromise paths. Enable `authorization: enabled`, restrict `bindIp` to internal addresses, and enable TLS. These three stop most attack paths. Add least-privilege accounts, iptables port control, and encrypted backups for defense in depth. Re-audit role permissions and connection audit logs quarterly.