Skip to main content

MongoDB Security

Authentication

Enable Authentication

# Start MongoDB with authentication
mongod --auth --dbpath /data/db

# Or in configuration file
security:
authorization: enabled

Create Admin User

// Connect without authentication first
use admin
db.createUser({
user: "admin",
pwd: "securePassword123",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" }
]
});

Create Database Users

// Application user with specific database access
use myapp
db.createUser({
user: "appUser",
pwd: "appPassword123",
roles: [
{ role: "readWrite", db: "myapp" }
]
});

// Read-only user
db.createUser({
user: "readOnlyUser",
pwd: "readPassword123",
roles: [
{ role: "read", db: "myapp" }
]
});

// Analytics user with read access to multiple databases
db.createUser({
user: "analyticsUser",
pwd: "analyticsPassword123",
roles: [
{ role: "read", db: "myapp" },
{ role: "read", db: "logs" },
{ role: "read", db: "metrics" }
]
});

Custom Roles

// Create custom role
use admin
db.createRole({
role: "dataAnalyst",
privileges: [
{
resource: { db: "myapp", collection: "" },
actions: ["find", "listCollections", "listIndexes"]
},
{
resource: { db: "analytics", collection: "" },
actions: ["find", "insert", "update"]
}
],
roles: []
});

// Assign custom role to user
db.createUser({
user: "analyst",
pwd: "analystPassword",
roles: ["dataAnalyst"]
});

Authorization

Built-in Roles

// Database roles
"read" // Read data from all non-system collections
"readWrite" // Read and write data to all non-system collections
"dbAdmin" // Database administration tasks
"dbOwner" // Full access to database
"userAdmin" // Manage users and roles for database

// Cluster roles
"clusterAdmin" // Full cluster administration
"clusterManager" // Manage and monitor cluster
"clusterMonitor" // Read-only access to monitoring tools
"hostManager" // Monitor and manage servers

// All-database roles
"readAnyDatabase" // Read from all databases
"readWriteAnyDatabase" // Read/write all databases
"userAdminAnyDatabase" // User admin for all databases
"dbAdminAnyDatabase" // Database admin for all databases

// Superuser roles
"root" // Full access to all resources

User Management

// List all users
db.getUsers();

// Get user info
db.getUser("username");

// Update user password
db.changeUserPassword("username", "newPassword");

// Grant additional roles
db.grantRolesToUser("username", ["read"]);

// Revoke roles
db.revokeRolesFromUser("username", ["write"]);

// Drop user
db.dropUser("username");

Network Security

IP Binding and Firewall

# Bind to specific IP addresses
mongod --bind_ip 127.0.0.1,192.168.1.100

# Configuration file
net:
bindIp: 127.0.0.1,192.168.1.100
port: 27017

SSL/TLS Configuration

# Enable SSL
mongod --sslMode requireSSL \
--sslPEMKeyFile /path/to/server.pem \
--sslCAFile /path/to/ca.pem

# Configuration file
net:
ssl:
mode: requireSSL
PEMKeyFile: /path/to/server.pem
CAFile: /path/to/ca.pem
allowConnectionsWithoutCertificates: false

Client SSL Connection

# Python with SSL
from pymongo import MongoClient

client = MongoClient(
'mongodb://username:password@hostname:27017/database',
ssl=True,
ssl_cert_reqs='CERT_REQUIRED',
ssl_ca_certs='/path/to/ca.pem',
ssl_certfile='/path/to/client.pem'
)
// Node.js with SSL
const { MongoClient } = require('mongodb');

const client = new MongoClient(uri, {
ssl: true,
sslValidate: true,
sslCA: fs.readFileSync('/path/to/ca.pem'),
sslCert: fs.readFileSync('/path/to/client.pem'),
sslKey: fs.readFileSync('/path/to/client-key.pem')
});

Encryption

Encryption at Rest

# Enable encryption at rest
mongod --enableEncryption \
--encryptionKeyFile /path/to/key/file

# Configuration file
security:
enableEncryption: true
encryptionKeyFile: /path/to/key/file

Field-Level Encryption

// Client-side field level encryption setup
const clientEncryption = new ClientEncryption(keyVaultClient, {
keyVaultNamespace: 'encryption.__keyVault',
kmsProviders: {
local: {
key: localMasterKey
}
}
});

// Create data encryption key
const dataKeyId = await clientEncryption.createDataKey('local');

// Encrypt field
const encryptedField = await clientEncryption.encrypt(
'sensitive data',
{
keyId: dataKeyId,
algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'
}
);

Auditing

Enable Auditing

# Enable audit logging
mongod --auditDestination file \
--auditFormat JSON \
--auditPath /var/log/mongodb/audit.json

# Configuration file
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.json
filter: '{ atype: { $in: ["createUser", "dropUser"] } }'

Audit Filters

// Audit all authentication events
{
atype: {
$in: ["authenticate", "authCheck"]
}
}

// Audit user management operations
{
atype: {
$in: ["createUser", "dropUser", "updateUser", "grantRolesToUser"]
}
}

// Audit data access on sensitive collections
{
"ns": "myapp.users",
"atype": {
$in: ["find", "update", "delete"]
}
}

Security Best Practices

MongoDB Configuration Security

# Secure mongod.conf
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true

storage:
dbPath: /var/lib/mongodb
journal:
enabled: true

processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid

net:
port: 27017
bindIp: 127.0.0.1 # Bind to localhost only

security:
authorization: enabled
keyFile: /etc/mongodb/replica-set-key # For replica sets

# Enable auditing in production
auditLog:
destination: file
format: JSON
path: /var/log/mongodb/audit.json

Connection String Security

// Use environment variables for credentials
const uri = `mongodb://${process.env.DB_USER}:${process.env.DB_PASS}@${process.env.DB_HOST}:27017/${process.env.DB_NAME}`;

// Use connection pooling
const client = new MongoClient(uri, {
maxPoolSize: 50,
minPoolSize: 5,
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
retryWrites: true
});

Input Validation and Sanitization

# Python - Validate input
from bson import ObjectId
from bson.errors import InvalidId

def validate_object_id(id_string):
try:
return ObjectId(id_string)
except InvalidId:
raise ValueError("Invalid ObjectId")

# Sanitize user input
import re

def sanitize_string(input_string):
# Remove potential injection characters
return re.sub(r'[^a-zA-Z0-9\s]', '', input_string)

# Use parameterized queries (automatic with MongoDB drivers)
user = collection.find_one({"email": user_email}) # Safe
# Never do: collection.find_one(f"{{email: '{user_email}'}}")
// Node.js - Input validation
const { ObjectId } = require('mongodb');

function validateObjectId(id) {
if (!ObjectId.isValid(id)) {
throw new Error('Invalid ObjectId');
}
return new ObjectId(id);
}

// Rate limiting middleware (Express.js)
const rateLimit = require('express-rate-limit');

const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: 'Too many requests from this IP'
});

app.use('/api/', limiter);

Monitoring and Alerting

// Monitor failed authentication attempts
db.adminCommand({
getLog: "global"
}).log.forEach(function(entry) {
if (entry.includes("Authentication failed")) {
print("Failed auth: " + entry);
}
});

// Set up alerts for security events
const MongoClient = require('mongodb').MongoClient;

async function monitorSecurity() {
const client = new MongoClient(uri);
await client.connect();

const changeStream = client.db('admin').watch([
{
$match: {
'operationType': 'insert',
'ns.coll': 'system.users'
}
}
]);

changeStream.on('change', (change) => {
console.log('User created:', change.fullDocument);
// Send alert to security team
});
}

Environment-Specific Security

# Development environment
export MONGO_URI="mongodb://localhost:27017/myapp_dev"
export MONGO_AUTH_ENABLED=false

# Staging environment
export MONGO_URI="mongodb://user:pass@staging-host:27017/myapp_staging"
export MONGO_AUTH_ENABLED=true
export MONGO_SSL_ENABLED=true

# Production environment
export MONGO_URI="mongodb+srv://user:pass@prod-cluster.mongodb.net/myapp"
export MONGO_AUTH_ENABLED=true
export MONGO_SSL_ENABLED=true
export MONGO_AUDIT_ENABLED=true

Security Checklist

- [ ] Enable authentication on all MongoDB instances
- [ ] Create users with minimal required privileges
- [ ] Use strong passwords and rotate them regularly
- [ ] Enable SSL/TLS for all connections
- [ ] Bind MongoDB to specific IP addresses
- [ ] Configure firewall rules to limit access
- [ ] Enable auditing for compliance requirements
- [ ] Encrypt sensitive data at rest
- [ ] Use field-level encryption for PII
- [ ] Implement proper input validation
- [ ] Monitor for security events and failed logins
- [ ] Keep MongoDB version updated
- [ ] Use MongoDB Atlas for managed security
- [ ] Implement connection pooling limits
- [ ] Use environment variables for credentials
- [ ] Regular security assessments and penetration testing