Vulnerabilidade Critica no MongoDB Expoe Mais de 87 Mil Servidores
Olá HaWkers, uma notícia preocupante acaba de surgir no mundo da segurança: pesquisadores descobriram que mais de 87 mil servidores MongoDB estão expostos na internet com uma vulnerabilidade crítica que permite acesso não autorizado a dados sensíveis.
Se você usa MongoDB em produção, este artigo é essencial. Vamos entender o que aconteceu, como verificar se seu servidor está vulnerável, e principalmente como se proteger.
O Que Aconteceu
Pesquisadores de segurança identificaram uma combinação de configurações inseguras e uma nova CVE que afeta versões específicas do MongoDB. O mais alarmante é que muitos desses servidores estão completamente abertos, sem qualquer autenticação.
Números Alarmantes
Escala do problema:
- 87.000+ servidores MongoDB expostos publicamente
- 40% sem qualquer autenticação habilitada
- 23.000+ contêm dados sensíveis (emails, senhas, PII)
- Brasil está entre os 10 países mais afetados
- 12.000+ já foram comprometidos por ransomware
Versões mais afetadas:
- MongoDB 4.4.x (antes de 4.4.28)
- MongoDB 5.0.x (antes de 5.0.24)
- MongoDB 6.0.x (antes de 6.0.13)
- MongoDB 7.0.x (antes de 7.0.5)
⚠️ Urgente: Se você usa MongoDB em produção, verifique imediatamente sua versão e configurações de segurança.
Verificando Se Seu Servidor Está Vulnerável
O primeiro passo é identificar se sua instalação está em risco. Aqui estão comandos e verificações essenciais:
Verificação Rápida de Exposição
// Conecte ao seu MongoDB e execute:
// Verificar versão
db.version()
// Verificar se autenticação está habilitada
db.adminCommand({ getParameter: 1, authenticationMechanisms: 1 })
// Listar usuários (se vazio, você está em risco!)
db.getUsers()
// Verificar bind IP
db.adminCommand({ getCmdLineOpts: 1 })Script de Auditoria de Segurança
Crie um script para verificar múltiplas configurações:
// audit-mongodb-security.js
// Execute com: mongosh < audit-mongodb-security.js
print("=== MongoDB Security Audit ===\n");
// 1. Verificar versão
const version = db.version();
print(`MongoDB Version: ${version}`);
// Versões vulneráveis conhecidas
const vulnerableVersions = ["4.4.0", "4.4.27", "5.0.0", "5.0.23", "6.0.0", "6.0.12", "7.0.0", "7.0.4"];
if (vulnerableVersions.some(v => version.startsWith(v.split('.').slice(0, 2).join('.')))) {
print("⚠️ ALERTA: Versão pode conter vulnerabilidades conhecidas!");
} else {
print("✅ Versão parece estar atualizada");
}
// 2. Verificar autenticação
try {
const authMechanisms = db.adminCommand({ getParameter: 1, authenticationMechanisms: 1 });
print(`\nAuthentication Mechanisms: ${JSON.stringify(authMechanisms.authenticationMechanisms)}`);
if (authMechanisms.authenticationMechanisms.length === 0) {
print("⚠️ CRÍTICO: Nenhum mecanismo de autenticação configurado!");
}
} catch (e) {
print("ℹ️ Não foi possível verificar mecanismos de autenticação");
}
// 3. Verificar usuários
try {
const users = db.getUsers();
print(`\nTotal de usuários configurados: ${users.users.length}`);
if (users.users.length === 0) {
print("⚠️ CRÍTICO: Nenhum usuário configurado! Servidor aberto!");
} else {
print("✅ Usuários configurados encontrados");
}
} catch (e) {
print("ℹ️ Execute como admin para verificar usuários");
}
// 4. Verificar bind address
try {
const cmdLineOpts = db.adminCommand({ getCmdLineOpts: 1 });
const bindIp = cmdLineOpts.parsed?.net?.bindIp || "não especificado";
print(`\nBind IP: ${bindIp}`);
if (bindIp === "0.0.0.0" || bindIp.includes("0.0.0.0")) {
print("⚠️ ALERTA: Servidor acessível de qualquer IP!");
} else if (bindIp === "127.0.0.1" || bindIp === "localhost") {
print("✅ Servidor acessível apenas localmente");
}
} catch (e) {
print("ℹ️ Execute como admin para verificar bind IP");
}
// 5. Verificar SSL/TLS
try {
const sslInfo = db.adminCommand({ getParameter: 1, sslMode: 1 });
print(`\nSSL Mode: ${sslInfo.sslMode || 'disabled'}`);
if (!sslInfo.sslMode || sslInfo.sslMode === "disabled") {
print("⚠️ ALERTA: SSL/TLS não está habilitado!");
} else {
print("✅ SSL/TLS está configurado");
}
} catch (e) {
print("ℹ️ Não foi possível verificar SSL/TLS");
}
print("\n=== Fim da Auditoria ===");
Configuração Segura do MongoDB
Se você identificou problemas, aqui está como corrigi-los corretamente:
1. Habilitar Autenticação
Primeiro, crie um usuário administrador:
// Conecte sem autenticação primeiro
// mongosh --host localhost
// Troque para o database admin
use admin
// Criar usuário administrador
db.createUser({
user: "adminUser",
pwd: passwordPrompt(), // Solicita senha de forma segura
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "dbAdminAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" }
]
})
// Criar usuário para aplicação (privilégios mínimos)
use myAppDatabase
db.createUser({
user: "appUser",
pwd: passwordPrompt(),
roles: [
{ role: "readWrite", db: "myAppDatabase" }
]
})2. Configuração do mongod.conf
Atualize seu arquivo de configuração para máxima segurança:
# /etc/mongod.conf
# Rede - NUNCA use 0.0.0.0 em produção
net:
port: 27017
bindIp: 127.0.0.1 # Apenas localhost
# Para acesso remoto específico:
# bindIp: 127.0.0.1,192.168.1.100
# TLS/SSL (recomendado)
tls:
mode: requireTLS
certificateKeyFile: /etc/ssl/mongodb.pem
CAFile: /etc/ssl/ca.pem
# Segurança - SEMPRE habilite
security:
authorization: enabled
javascriptEnabled: false # Desabilita JavaScript no servidor
# Para clusters
# keyFile: /etc/mongodb-keyfile
# Logging para auditoria
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
verbosity: 1
# Limites de operação
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
# Storage
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
3. Configuração de Firewall
Configure regras de firewall para proteger ainda mais:
# UFW (Ubuntu/Debian)
# Bloquear acesso externo ao MongoDB
sudo ufw deny 27017
# Permitir apenas IPs específicos
sudo ufw allow from 192.168.1.0/24 to any port 27017
# iptables
# Bloquear todo acesso externo
sudo iptables -A INPUT -p tcp --dport 27017 -j DROP
# Permitir apenas localhost
sudo iptables -A INPUT -p tcp -s 127.0.0.1 --dport 27017 -j ACCEPT
# Permitir IP específico
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 27017 -j ACCEPT4. Proteção com Docker
Se você usa Docker, configure corretamente:
# docker-compose.yml
version: '3.8'
services:
mongodb:
image: mongo:7.0
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD_FILE: /run/secrets/mongo_root_password
ports:
# NUNCA exponha diretamente - use apenas rede interna
- "127.0.0.1:27017:27017"
volumes:
- mongodb_data:/data/db
- ./mongod.conf:/etc/mongod.conf:ro
command: ["mongod", "--config", "/etc/mongod.conf"]
secrets:
- mongo_root_password
networks:
- backend
# Limites de recursos
deploy:
resources:
limits:
memory: 2G
reservations:
memory: 512M
secrets:
mongo_root_password:
file: ./secrets/mongo_password.txt
volumes:
mongodb_data:
networks:
backend:
internal: true # Rede isolada
Conexão Segura em Aplicações Node.js
Atualize sua aplicação para usar conexões seguras:
// config/database.js
const mongoose = require('mongoose');
const mongoConfig = {
// Use variáveis de ambiente para credenciais
uri: process.env.MONGODB_URI,
options: {
// Autenticação
authSource: 'admin',
authMechanism: 'SCRAM-SHA-256',
// TLS/SSL
tls: true,
tlsCAFile: process.env.MONGODB_CA_CERT,
tlsCertificateKeyFile: process.env.MONGODB_CLIENT_CERT,
// Pool de conexões
maxPoolSize: 10,
minPoolSize: 2,
// Timeouts
serverSelectionTimeoutMS: 5000,
socketTimeoutMS: 45000,
connectTimeoutMS: 10000,
// Retry
retryWrites: true,
retryReads: true,
// Compressão
compressors: ['zstd', 'snappy', 'zlib'],
}
};
async function connectDatabase() {
try {
// Validar URI antes de conectar
if (!mongoConfig.uri) {
throw new Error('MONGODB_URI não configurada');
}
// Conectar com retry
await mongoose.connect(mongoConfig.uri, mongoConfig.options);
console.log('✅ MongoDB conectado com sucesso');
// Handlers de eventos
mongoose.connection.on('error', (err) => {
console.error('❌ Erro MongoDB:', err);
});
mongoose.connection.on('disconnected', () => {
console.warn('⚠️ MongoDB desconectado');
});
} catch (error) {
console.error('❌ Falha ao conectar MongoDB:', error);
process.exit(1);
}
}
// Graceful shutdown
process.on('SIGINT', async () => {
await mongoose.connection.close();
console.log('MongoDB desconectado via SIGINT');
process.exit(0);
});
module.exports = { connectDatabase, mongoConfig };Exemplo com Driver Nativo
// Para conexões sem Mongoose
const { MongoClient } = require('mongodb');
async function createSecureClient() {
const client = new MongoClient(process.env.MONGODB_URI, {
// Autenticação forte
auth: {
username: process.env.MONGODB_USER,
password: process.env.MONGODB_PASSWORD,
},
authMechanism: 'SCRAM-SHA-256',
authSource: 'admin',
// TLS obrigatório
tls: true,
tlsAllowInvalidCertificates: false,
tlsAllowInvalidHostnames: false,
// Validação de certificado
tlsCAFile: '/path/to/ca.pem',
// Limites de segurança
maxPoolSize: 10,
serverSelectionTimeoutMS: 5000,
// Monitoramento
monitorCommands: true,
});
// Listener para comandos (auditoria)
client.on('commandStarted', (event) => {
// Log apenas em desenvolvimento
if (process.env.NODE_ENV === 'development') {
console.log(`Command: ${event.commandName}`);
}
});
await client.connect();
return client;
}
module.exports = { createSecureClient };
Monitoramento e Detecção de Intrusões
Configure alertas para detectar atividades suspeitas:
Script de Monitoramento
// monitor-mongodb-security.js
const { MongoClient } = require('mongodb');
class MongoDBSecurityMonitor {
constructor(uri) {
this.uri = uri;
this.alerts = [];
}
async checkForSuspiciousActivity() {
const client = new MongoClient(this.uri);
try {
await client.connect();
const admin = client.db('admin');
// 1. Verificar conexões ativas
const currentOps = await admin.command({ currentOp: 1, active: true });
const suspiciousOps = currentOps.inprog.filter(op =>
op.client && !op.client.startsWith('127.0.0.1')
);
if (suspiciousOps.length > 0) {
this.alert('CONEXÕES EXTERNAS DETECTADAS', suspiciousOps);
}
// 2. Verificar tentativas de login
const logs = await admin.command({
getLog: 'global'
});
const authFailures = logs.log.filter(l =>
l.includes('authentication failed')
);
if (authFailures.length > 10) {
this.alert('MÚLTIPLAS FALHAS DE AUTENTICAÇÃO', {
count: authFailures.length,
recent: authFailures.slice(-5)
});
}
// 3. Verificar comandos perigosos
const dangerousCommands = ['dropDatabase', 'dropCollection', 'eval'];
// Implementar verificação de logs
console.log('✅ Verificação de segurança concluída');
return this.alerts;
} finally {
await client.close();
}
}
alert(type, details) {
const alert = {
timestamp: new Date(),
type,
details,
severity: 'HIGH'
};
this.alerts.push(alert);
console.error(`🚨 ALERTA: ${type}`, details);
// Aqui você pode integrar com Slack, email, PagerDuty, etc.
}
}
module.exports = { MongoDBSecurityMonitor };
Boas Práticas de Segurança MongoDB
Para garantir segurança contínua, siga estas práticas:
Checklist de Segurança
Configuração básica:
- Autenticação habilitada com SCRAM-SHA-256
- Usuários com privilégios mínimos necessários
- Bind IP restrito (nunca 0.0.0.0)
- Firewall configurado corretamente
Criptografia:
- TLS/SSL habilitado para todas as conexões
- Certificados válidos e atualizados
- Encryption at rest habilitado
Monitoramento:
- Logs de auditoria habilitados
- Alertas para atividades suspeitas
- Backup regular e testado
- Plano de resposta a incidentes
Atualizações:
- MongoDB atualizado para última versão estável
- Drivers atualizados
- Patches de segurança aplicados
Conclusão
A vulnerabilidade que afetou 87 mil servidores MongoDB é um lembrete importante de que segurança não pode ser deixada para depois. Muitas dessas exposições poderiam ser evitadas com configurações básicas que levam minutos para implementar.
Se você usa MongoDB em produção, reserve um tempo hoje para verificar suas configurações e implementar as proteções necessárias. A segurança dos dados dos seus usuários depende disso.
Se você se sente inspirado a aprender mais sobre segurança em desenvolvimento, recomendo que dê uma olhada em outro artigo: Segurança em APIs REST: Guia Completo onde você vai descobrir como proteger seus endpoints de ataques comuns.

