Section 7: Advanced Topics

🔒 MongoDB Security

Master authentication, authorization, encryption, and production security best practices

🚨 The $5 Million Data Breach

A startup deployed MongoDB with default settings. No authentication, no firewall, port 27017 open to the internet.

Result: Hackers found it in 2 hours. Deleted 500GB of customer data. Demanded $50K ransom. Company lost $5M in lawsuits and went bankrupt.

Prevention: Enable authentication + firewall rules. Would have taken 5 minutes to configure. ✨

⚠️ Never deploy MongoDB without security! This happens to real companies every week.

🛡️ Defense in Depth: Security Layers

MongoDB security uses multiple layers. If one fails, others protect your data.

Layer 1: Network Security

Firewall rules, VPN, IP whitelisting, private networks

Layer 2: Authentication

Verify WHO is connecting (username/password, certificates, LDAP)

Layer 3: Authorization

Control WHAT they can do (role-based access control)

Layer 4: Encryption

Encrypt data in transit (TLS/SSL) and at rest

Layer 5: Auditing

Log all access attempts and operations for compliance

🔐 Authentication: Verify Identity

Enable Authentication (First Step!)

# Step 1: Create admin user
mongosh
use admin
db.createUser({
  user: "admin",
  pwd: "StrongPassword123!",
  roles: ["userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase"]
})

# Step 2: Enable auth in mongod.conf
security:
  authorization: enabled

# Step 3: Restart MongoDB
sudo systemctl restart mongod

# Step 4: Connect with authentication
mongosh -u admin -p StrongPassword123! --authenticationDatabase admin

Authentication Mechanisms

1. SCRAM (Default - Recommended)

// Salted Challenge Response Authentication Mechanism
db.createUser({
  user: "appUser",
  pwd: passwordPrompt(),  // Secure password input
  roles: ["readWrite"]
})

2. x.509 Certificate Authentication

// For internal cluster communication
mongod --tlsMode requireTLS \
  --tlsCertificateKeyFile /path/to/server.pem \
  --tlsCAFile /path/to/ca.pem

3. LDAP (Enterprise)

// Integrate with Active Directory
security:
  authorization: enabled
  ldap:
    servers: "ldap.example.com"
    authz:
      queryTemplate: "DC=example,DC=com??sub?(uid={USER})"
🔑 Password Best Practices:
  • Minimum 15 characters
  • Mix uppercase, lowercase, numbers, symbols
  • Never hardcode in application code
  • Use environment variables or secret managers
  • Rotate passwords every 90 days

👮 Authorization: Control Access

Built-in Roles

// Database User Roles
read              // Read any database
readWrite         // Read and write any database

// Database Admin Roles  
dbAdmin           // Database administration
dbOwner           // Database owner (admin + readWrite)
userAdmin         // Create and modify roles/users

// Cluster Admin Roles
clusterAdmin      // Cluster administration
clusterManager    // Manage and monitor cluster
clusterMonitor    // Read-only access to monitoring

// Backup/Restore Roles
backup            // Backup data
restore           // Restore data

// Super User Role
root              // All privileges (use sparingly!)

Create Users with Specific Roles

// Read-only user for analytics
db.createUser({
  user: "analyst",
  pwd: "SecurePass456!",
  roles: [{ role: "read", db: "sales" }]
})

// Application user with read-write on specific DB
db.createUser({
  user: "appUser",
  pwd: "AppPass789!",
  roles: [{ role: "readWrite", db: "production" }]
})

// DBA with admin privileges
db.createUser({
  user: "dba",
  pwd: "DBAPass321!",
  roles: [
    { role: "dbAdminAnyDatabase", db: "admin" },
    { role: "clusterAdmin", db: "admin" }
  ]
})

Custom Roles (Fine-Grained Control)

// Create role that can only read specific collection
use admin
db.createRole({
  role: "ordersReader",
  privileges: [{
    resource: { db: "sales", collection: "orders" },
    actions: ["find", "listCollections", "listIndexes"]
  }],
  roles: []
})

// Assign to user
db.createUser({
  user: "orderViewer",
  pwd: "ViewPass999!",
  roles: ["ordersReader"]
})

Verify User Permissions

// Show current user's roles
db.runCommand({ connectionStatus: 1 })

// List all users
db.getUsers()

// Show user privileges
db.getUser("appUser", { showPrivileges: true })

🔐 Encryption: Protect Data

1. Encryption in Transit (TLS/SSL)

# Generate certificates (production: use proper CA)
openssl req -newkey rsa:2048 -nodes -keyout mongodb.key -x509 -days 365 -out mongodb.crt
cat mongodb.key mongodb.crt > mongodb.pem

# Configure mongod.conf
net:
  tls:
    mode: requireTLS
    certificateKeyFile: /path/to/mongodb.pem
    CAFile: /path/to/ca.pem

# Connect with TLS
mongosh "mongodb://localhost:27017" \
  --tls \
  --tlsCertificateKeyFile /path/to/client.pem

2. Encryption at Rest (Enterprise)

# Create encryption key
openssl rand -base64 32 > mongodb-keyfile

# Configure encryption
security:
  enableEncryption: true
  encryptionKeyFile: /path/to/mongodb-keyfile
  encryptionCipherMode: AES256-CBC

# Restart MongoDB - all data encrypted!

3. Client-Side Field Level Encryption (CSFLE)

// Encrypt sensitive fields before sending to DB
const clientEncryption = new ClientEncryption(keyVaultClient, {
  keyVaultNamespace: 'encryption.__keyVault',
  kmsProviders: { local: { key: masterKey } }
})

// Encrypt SSN field
const encryptedSSN = await clientEncryption.encrypt(
  '123-45-6789',
  {
    algorithm: 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic',
    keyId: dataKey
  }
)

// Store encrypted value
await db.users.insertOne({
  name: 'John Doe',
  ssn: encryptedSSN  // Encrypted in DB
})
💡 Encryption Tip:

TLS = encrypt network traffic, At-Rest = encrypt disk, CSFLE = encrypt specific fields. Use all three for maximum security!

🌐 Network Security

1. Bind to Private IP Only

# NEVER bind to 0.0.0.0 in production!
# mongod.conf
net:
  bindIp: 127.0.0.1,10.0.1.5  # localhost + private IP
  port: 27017

2. Firewall Rules

# Allow only application servers
sudo ufw allow from 10.0.1.10 to any port 27017
sudo ufw allow from 10.0.1.11 to any port 27017
sudo ufw deny 27017

# For AWS Security Groups
{
  "IpProtocol": "tcp",
  "FromPort": 27017,
  "ToPort": 27017,
  "IpRanges": [{ "CidrIp": "10.0.1.0/24" }]
}

3. VPC and Private Networks

# Best practice: Deploy in private subnet
VPC: 10.0.0.0/16
  ├─ Public Subnet:  10.0.1.0/24 (NAT Gateway)
  └─ Private Subnet: 10.0.2.0/24 (MongoDB here!)

# MongoDB only accessible from within VPC
# No public IP, no internet access

4. Change Default Port (Security by Obscurity)

# mongod.conf
net:
  port: 37017  # Not 27017 - reduces automated attacks

# Note: This is NOT a replacement for real security!

📋 Auditing & Compliance

Enable Audit Logging (Enterprise)

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

# Audit events logged:
// - Authentication attempts (success/failure)
// - User creation/deletion  
// - Database/collection drops
// - Role changes
// - Configuration changes

Audit Log Analysis

# Find failed login attempts
grep '"atype":"authenticate"' audit.json | grep '"result":5'

# Find user creation events
grep '"atype":"createUser"' audit.json

# Find dropped databases (disaster prevention!)
grep '"atype":"dropDatabase"' audit.json

Compliance Requirements

  • GDPR: Encryption, audit logs, data deletion capabilities
  • HIPAA: At-rest encryption, access controls, audit trails
  • PCI DSS: Network segmentation, encryption, strong auth
  • SOC 2: Monitoring, logging, incident response

⭐ Security Best Practices

  1. Enable Authentication - ALWAYS, even in dev environments
  2. Use Role-Based Access Control - Principle of least privilege
  3. Enable TLS/SSL - Encrypt all network traffic
  4. Encrypt at Rest - Protect data on disk (Enterprise feature)
  5. Bind to Private IPs - Never expose to internet
  6. Configure Firewall - Whitelist only trusted IPs
  7. Regular Updates - Apply security patches promptly
  8. Strong Passwords - 15+ chars, rotated every 90 days
  9. Enable Audit Logging - Track all security events
  10. Disable Unused Features - Reduce attack surface
  11. Backup Encryption Keys - Store securely, separate from data
  12. Monitor Security Logs - Alert on suspicious activity
  13. Use Secrets Manager - Don't hardcode credentials
  14. Regular Security Audits - Penetration testing annually
  15. Incident Response Plan - Know what to do when breached

💼 Interview Questions & Answers

Q1 What are the main security layers in MongoDB? ▼

Defense in Depth - 5 Layers:

  1. Network Security: Firewalls, VPC, IP whitelisting
  2. Authentication: Verify WHO (SCRAM, x.509, LDAP)
  3. Authorization: Control WHAT (RBAC, roles)
  4. Encryption: TLS (transit) + at-rest + CSFLE
  5. Auditing: Log access and operations

Key principle: If one layer fails, others still protect data

Q2 Difference between authentication and authorization? ▼

Authentication: Verifies WHO you are (identity)

  • Username + password
  • Certificates (x.509)
  • LDAP integration
  • Question: "Are you really Alice?"

Authorization: Controls WHAT you can do (permissions)

  • Role-based access control
  • Read/write permissions
  • Database/collection access
  • Question: "Can Alice delete this database?"

Example: You authenticate as "admin" → Authorization allows you to create users

Q3 How do you enable authentication in MongoDB? ▼

Step-by-step process:

// 1. Create admin user (before enabling auth)
use admin
db.createUser({
  user: "admin",
  pwd: "StrongPassword",
  roles: ["userAdminAnyDatabase"]
})

// 2. Enable auth in mongod.conf
security:
  authorization: enabled

// 3. Restart MongoDB
sudo systemctl restart mongod

// 4. Connect with credentials
mongosh -u admin -p StrongPassword --authenticationDatabase admin

⚠️ Important: Create admin user BEFORE enabling auth, or you'll lock yourself out!

Q4 What is the difference between TLS and encryption at rest? ▼

TLS/SSL (Encryption in Transit):

  • Encrypts data traveling over network
  • Protects against network sniffing/eavesdropping
  • Client ↔ MongoDB communication encrypted
  • Required: Certificate files (.pem)

Encryption at Rest:

  • Encrypts data stored on disk
  • Protects against disk theft/unauthorized access
  • Database files encrypted
  • Required: Encryption key file (Enterprise only)

Best practice: Use BOTH - TLS for network + at-rest for storage

Q5 What are common MongoDB security mistakes? ▼

Top 10 Security Mistakes:

  1. No Authentication Enabled - Anyone can connect!
  2. Binding to 0.0.0.0 - Exposed to internet
  3. Weak Passwords - "admin" / "password123"
  4. No Firewall Rules - Port 27017 open to world
  5. No TLS/SSL - Credentials sent in plaintext
  6. Using 'root' Role - Too much privilege
  7. Hardcoded Credentials - In source code/config
  8. No Audit Logging - Can't detect breaches
  9. Outdated Version - Missing security patches
  10. No Monitoring - Don't notice attacks

Result: Most breaches happen because of #1-4 combined!

Q6 How do you implement role-based access control? ▼

RBAC Implementation Strategy:

// 1. Identify user types and permissions needed
// - Developers: read/write on dev DB
// - Analysts: read-only on production
// - DBAs: admin on all databases

// 2. Create users with appropriate roles
// Developer
db.createUser({
  user: "dev1",
  pwd: "DevPass",
  roles: [{ role: "readWrite", db: "dev_db" }]
})

// Analyst  
db.createUser({
  user: "analyst1",
  pwd: "AnalystPass",
  roles: [{ role: "read", db: "production_db" }]
})

// DBA
db.createUser({
  user: "dba1",
  pwd: "DBAPass",
  roles: ["dbAdminAnyDatabase", "clusterAdmin"]
})

// 3. Create custom roles for fine-grained control
db.createRole({
  role: "customerDataReader",
  privileges: [{
    resource: { db: "crm", collection: "customers" },
    actions: ["find", "listIndexes"]
  }],
  roles: []
})

Best practice: Principle of least privilege - give only minimum required permissions