Os aplicativos MongoDB correm sérios riscos de segurança quando as entradas do usuário não são validadas. Os ataques de injeção nosql podem invadir silenciosamente seu banco de dados, expondo dados confidenciais e comprometendo a integridade do sistema. Este guia mostra estratégias defensivas comprovadas para limpar entradas, proteger consultas a bancos de dados e criar uma proteção robusta contra ameaças baseadas em injeção.
O que é injeção nosql?
A injeção nosql rola quando os invasores usam entradas de usuário mal validadas pra mexer com a lógica de consulta do banco de dados. Ao injetar cargas maliciosas, os invasores podem passar por cima dos mecanismos de autenticação, pegar dados sem autorização ou burlar os controles de segurança dos aplicativos.
Diferente da injeção SQL, que usa vulnerabilidades na construção de consultas baseadas em strings, a injeção nosql aproveita estruturas de dados flexíveis e consultas dinâmicas. Isso é especialmente perigoso quando os aplicativos aceitam entradas mal definidas, como interface{} ou map[string]interface{} sem a validação adequada.
Por que o MongoDB é diferente
As consultas MongoDB são criadas usando objetos BSON (Binary JSON) — pares de chave-valor estruturados — em vez de strings brutas. Esse design evita muitos riscos tradicionais de injeção, porque as consultas não são montadas por meio da concatenação de strings.
Mas, se a entrada do usuário for colocada diretamente nesses objetos BSON sem a validação certa, os invasores podem colocar operadores MongoDB como $ne, $gtou $or para alterar a lógica da consulta.
Exemplo: injeção de operador em Go
filter := bson.M{"name": inputName}
collection.Find(ctx, filter)
Se inputName for uma string simples como “Joe”, está tudo bem. Mas se o seu código aceita map[string]interface{} ou JSON bruto, um invasor pode injetar objetos operadores como:
{ "$ne": null }
Essa carga útil transforma a lógica da consulta, correspondendo a qualquer documento em que o nome exista, em vez de filtrar por um valor específico — efetivamente contornando os controles de acesso pretendidos pelo aplicativo.
Reconhecendo padrões inseguros e armadilhas comuns
1. Confiança implícita nos corpos das solicitações
A análise direta dos corpos das solicitações em mapas BSON cria um caminho de injeção onde os invasores podem colocar operadores de consulta maliciosos e construções lógicas complexas diretamente nas operações do banco de dados.
// Unsafe
var filter bson.M
_ = json.NewDecoder(req.Body).Decode(&filter)
Em vez disso, analise só os campos e tipos conhecidos:
type QueryInput struct {
Name string json:"name" validate:"required"
}
2. Aceitando tipos flexíveis
As vulnerabilidades de injeção geralmente aparecem quando as APIs aceitam tipos de dados muito permissivos, como interface{} ou mapas genéricos. Essas estruturas flexíveis podem conter operadores MongoDB incorporados ou construções de objetos maliciosos que contornam a lógica de consulta pretendida.
Minimize o uso de amarrações soltas, a menos que seja absolutamente necessário, e faça uma validação rigorosa quando for inevitável. Em vez disso, defina estruturas de dados explícitas que correspondam ao formato de entrada esperado e restrinjam os valores aceitáveis.
3. JSON em strings de consulta ou operadores de consulta
As APIs que mostram recursos de filtragem dinâmica por meio de parâmetros de consulta de URL ou pontos finais de pesquisa são alvos atraentes para ataques. Os invasores costumam atacar essas interfaces colocando operadores codificados em JSON e lógica condicional diretamente nas cadeias de consulta. Isso transforma parâmetros de filtro legítimos em operações maliciosas no banco de dados:
GET /search?filter={"price":{"$gt":0}}
Sem uma validação rigorosa das entradas, essa abordagem permite que invasores manipulem estruturas de consulta e contornem controles de segurança, potencialmente expondo dados não autorizados ou aumentando privilégios além dos níveis de acesso pretendidos.
Mitigação:
- Use listas de permissões de campos e operadores pra limitar os parâmetros de consulta a valores pré-definidos e seguros.
- Envolva explicitamente todos os valores fornecidos pelo usuário em operadores $eq ao criar filtros de banco de dados para evitar a injeção de operadores alternativos.
4. Expandindo consultas lógicas com injeção
Aplicativos que permitem ao usuário controlar operadores lógicos, como $or criam oportunidades para ataques de expansão de consulta. Os invasores podem colocar expressões condicionais extras nesses operadores, mudando completamente a semântica da consulta e, assim, podendo passar por cima das verificações de autenticação ou das restrições de acesso aos dados.
filter := bson.M{
"$or": []bson.M{
{"role": "user"},
{"active": true},
},
}
Se a entrada do usuário mexer diretamente com o cláusula $or , os invasores podem injetar uma condição não autorizada:
{ "$or": [ {"role": "user"}, {"active": true}, {"isAdmin": true} ] }
Essa consulta modificada poderia ignorar os controles de acesso baseados em funções, potencialmente expondo dados administrativos ou concedendo privilégios elevados a usuários não autorizados. Evite a modificação dinâmica de operadores lógicos implementando uma validação rigorosa das entradas e evitando o controle direto do usuário sobre a estrutura da consulta.
GET /search?filter={"price":{"$gt":0}}
Sem uma validação rigorosa das entradas, essa abordagem permite que invasores manipulem estruturas de consulta e contornem controles de segurança, potencialmente expondo dados não autorizados.
Mitigação:
- Use listas de permissões para campos e operadores permitidos, rejeitando qualquer parâmetro de consulta fora desses limites pré-definidos.
- Faça a igualdade explícita funcionando envolvendo todas as entradas do usuário em $eq para evitar a substituição de operadores de comparação ou lógicos.
Recursos de execução do JavaScript
O MongoDB oferece vários recursos de execução de JavaScript no lado do servidor que podem trazer riscos de segurança, como:
Esses recursos criam uma exposição significativa à segurança e devem ser evitados, a menos que requisitos comerciais críticos exijam seu uso. Para evitar explorações, desative os scripts na configuração do MongoDB:
Para mongod:
--noscripting
Ou através do arquivo de configuração:
security:
javascriptEnabled: false
Aplique a mesma configuração aos mongos em uma implantação fragmentada mongos em uma implantação fragmentada.
Os operadores de consulta nativos do MongoDB oferecem funcionalidades completas que eliminam a necessidade de execução de JavaScript em praticamente todos os casos de uso. Evite completamente as cláusulas$where , a menos que você tenha controle total sobre a validação de entrada e o contexto de execução.
Como evitar injeções nosql
1. Valide rigorosamente as entradas
Implemente uma validação de tipo rigorosa que só aceite tipos de dados primitivos esperados, como strings, inteiros ou booleanos. Rejeite quaisquer objetos aninhados, matrizes ou nomes de campos não reconhecidos que possam conter operações incorporadas ou construções maliciosas.
type LoginInput struct {
Username string json:"username" validate:"required,alphanum"
Password string json:"password" validate:"required,min=8"
}
2. Não confie na estrutura das consultas dos usuários
Crie todas as consultas ao banco de dados usando mapeamentos de campos e modelos de consulta pré-definidos e controlados pelo aplicativo. Não deixe que o que o usuário digita mexa na arquitetura da consulta, nos operadores lógicos ou nas estruturas condicionais que podem bagunçar os padrões de acesso aos dados que você quer.
filter := bson.M{
"username": input.Username,
"password": input.Password,
}
Evite:
// Dangerous: allows injection of operators
_ = json.NewDecoder(req.Body).Decode(&filter)
A maioria dos drivers do MongoDB oferece construtores de consultas fortemente tipados que garantem a construção estruturada de consultas e evitam vulnerabilidades de injeção acidental. Aproveite essas interfaces nativas em vez de expor mapas de consulta brutos ou objetos BSON por meio de pontos finais de aplicativos.
filter := bson.M{
"username": input.Username,
"password": input.Password,
}
Evite:
// Dangerous: allows injection of operators
_ = json.NewDecoder(req.Body).Decode(&filter)
3. Bloqueio da injeção de operadores MongoDB
Evite que entradas controladas pelo usuário funcionem como operadores de consulta ou construções lógicas. Trate todos os dados do usuário como valores literais, em vez de componentes de consulta executáveis.
Em vez de:
filter := bson.M{
"status": input.Status,
}
Como usar:
filter := bson.M{
"status": bson.M{"$eq": input.Status},
}
Essa abordagem impõe uma correspondência de igualdade rigorosa e impede a execução de operadores injetados, como $ne, $inou $regex ou outros modificadores lógicos que poderiam ignorar a lógica de consulta pretendida.
4. Use o privilégio mínimo para usuários do banco de dados
Configure as conexões do banco de dados do aplicativo com contas de usuário que tenham só as permissões mínimas necessárias para as operações pretendidas. Evite usar credenciais de nível administrativo nas configurações do aplicativo para evitar possíveis danos causados por ataques de injeção bem-sucedidos.
5. Monitorar e testar
Implemente um registro completo para detectar padrões de consulta incomuns e estabeleça protocolos regulares de testes de segurança. Valide a segurança do endpoint tentando ataques de injeção usando cargas malformadas, como:
{ "$ne": null }
Confira se o aplicativo está rejeitando isso.
Casos de teste a considerar:
- Objetos em vez de strings: { "username": { "$ne": null } }
- Matrizes em vez de escalares: { "funções": [ { "$gt": "" } ] }
- Operadores como valores de consulta: { "campo": { "$regex": ".*" } }
Lista de verificação resumida
- Validação de entrada: Aplique tipos de dados rigorosos, valide formatos e rejeite campos inesperados.
- Construção da consulta: Crie todas as consultas usando esquemas pré-definidos e modelos controlados pelo aplicativo.
- Proteção do operador: Bloqueie os operadores MongoDB na entrada do usuário envolvendo os valores em $eq ou usando APIs tipadas.
- Server-side JavaScript: Tira as cláusulas $where e desativa a execução do JavaScript nas configurações de produção.
- Controle de acesso ao banco de dados: Configure as conexões do aplicativo com o mínimo de permissões necessárias, evitando credenciais administrativas.
- Testes e monitoramento: Faça testes de injeção regularmente e registre padrões de consulta anômalos.
Considerações finais
As vulnerabilidades de injeção nosql podem ser totalmente evitadas com práticas disciplinadas de codificação segura. Implementar uma validação rigorosa de entradas, construção estruturada de consultas e controles de segurança de defesa em profundidade permite que os desenvolvedores mantenham a flexibilidade e o desempenho das aplicações, ao mesmo tempo que eliminam vetores de ataque de injeção.
O sucesso depende de entender todo o fluxo de dados do seu aplicativo — desde a análise da solicitação inicial até a execução final da consulta. Adote uma abordagem de confiança zero para todas as fontes de entrada, implemente a validação nos limites do sistema e priorize os princípios de programação defensiva em toda a sua pilha de tecnologia.
Perguntas frequentes
Por que a injeção nosql é um risco se o MongoDB usa BSON em vez de strings?
A injeção ainda pode acontecer antes que o objeto BSON seja criado. Se a entrada do usuário for analisada em tipos flexíveis como map[string]interface{} ou interface{} sem validação, os invasores podem injetar operadores MongoDB como $ne ou $or e mexer na lógica da consulta.
É seguro decodificar um corpo de solicitação diretamente em um bson.M ou map[string]interface{}?
Não. Isso permite que os usuários insiram operadores de consulta aleatórios. Sempre mapeie os dados da solicitação para tipos rígidos (por exemplo, estruturas Go) e valide a entrada antes de criar consultas.
Qual é o problema em usar $where se a entrada é validada?
Mesmo que a entrada seja parcialmente validada, $where executa JavaScript no servidor. Qualquer erro na fuga ou validação pode levar à injeção de código. É mais seguro evitar completamente o $where ou desativar os scripts na sua configuração do MongoDB.
Como posso testar se meu endpoint está vulnerável a injeção nosql?
Tente injetar cargas úteis como:
{ "username": { "$ne": null } }
Se o endpoint devolver uma resposta válida ou ignorar a lógica (por exemplo, login), a entrada não está sendo validada ou restringida corretamente.
Qual é a melhor maneira de criar consultas com segurança em Go?
Use estruturas tipadas para entrada, evite decodificar em mapas genéricos e envolva os valores em $eq quando necessário. Nunca deixe o usuário definir operadores ou inserir partes da consulta diretamente.


