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