image

Acesse bootcamps ilimitados e +650 cursos

50
%OFF
Article image
Jarbas Júnior
Jarbas Júnior27/09/2023 19:32
Compartilhe

O que é NoSQL Injection e como ela pode comprometer seus bancos de dados e aplicações

    NoSQL é um termo que se refere a um conjunto de bancos de dados que não seguem o modelo relacional tradicional, ou seja, que não usam SQL (Structured Query Language) como linguagem de consulta. Alguns exemplos de bancos de dados NoSQL são MongoDB, Cassandra, Redis e CouchDB. Esses bancos de dados oferecem vantagens como escalabilidade, flexibilidade e performance, mas também apresentam alguns desafios de segurança, como a possibilidade de sofrerem ataques de NoSQL injection.

    Mas o que é NoSQL injection?

    NoSQL injection é um tipo de ataque que explora vulnerabilidades nos bancos de dados NoSQL para injetar comandos maliciosos e manipular ou acessar dados indevidamente. Esse ataque é semelhante ao SQL injection, que afeta os bancos de dados relacionais, mas com algumas diferenças na forma como é executado e prevenido.

    Um exemplo clássico de NoSQL injection é quando um atacante envia um parâmetro malicioso em uma requisição HTTP para uma aplicação web que utiliza MongoDB. Esse parâmetro pode alterar a consulta original e fazer com que o banco de dados retorne mais dados do que o esperado, ou até mesmo executar operações não autorizadas. Por exemplo, se a aplicação espera receber um parâmetro `username` para autenticar um usuário, o atacante pode enviar algo como:

    username[$ne]=
    

    Esse parâmetro faz com que a consulta original, que seria algo como:

    db.users.find({username: username})
    

    Seja alterada para:

    db.users.find({username: {$ne: ""}})
    

    Essa query retorna todos os usuários cujo nome de usuário não é igual a uma string vazia, ou seja, todos os usuários do banco de dados. Dessa forma, o atacante consegue burlar a autenticação e acessar dados sensíveis.

    image

    Outros exemplos de NoSQL injection são:

    - Usar operadores lógicos como `$or` ou `$and` para combinar condições e filtrar resultados. Por exemplo:

    password[$regex]=.*&password[$ne]=
    

    Esse parâmetro faz com que a consulta original, que seria algo como:

    db.users.find({password: password})
    

    Seja alterada para:

    db.users.find({password: {$regex: ".*", $ne: ""}})
    

    Essa consulta retorna todos os usuários cuja senha não é igual a uma string vazia, ou seja, todos os usuários do banco de dados.

    image

    - Usar operadores aritméticos como $gt ou $lt para comparar valores numéricos e ordenar resultados. Por exemplo:

    age[$gt]=0&age[$lt]=1000
    

    Esse parâmetro faz com que a consulta original, que seria algo como:

    db.users.find({age: age})
    

    Seja alterada para:

    db.users.find({age: {$gt: 0, $lt: 1000}})
    

    Essa consulta retorna todos os usuários cuja idade está entre 0 e 1000 anos, ou seja, todos os usuários do banco de dados.

    - Usar operadores especiais como $where ou $eval para executar código JavaScript de forma arbitrária no servidor do banco de dados. Por exemplo:

    $where=function(){return true;}
    

    Esse parâmetro faz com que a consulta original, que seria algo como:

    db.users.find({})
    

    Seja alterada para:

    db.users.find({$where: function(){return true;}})
    

    Essa consulta retorna todos os documentos da coleção users, pois a função sempre retorna verdadeiro. Imagine o quão problemático isso pode ser dentro de um ambiente corporativo, por exemplo. Além disso, o atacante pode usar esse parâmetro para executar outras ações maliciosas no servidor, como apagar dados ou criar novos documentos.

    E como se proteger do NoSQL injection?

    Existem algumas medidas que podem ser tomadas para evitar ou mitigar os riscos de NoSQL injection. Algumas delas são:

    - Validar e sanitizar os dados de entrada: antes de enviar os dados para o banco de dados, é importante verificar se eles estão no formato esperado e remover ou tratar qualquer caractere especial que possa, de algum modo, alterar a consulta original. Isso é válido tanto no front-end quanto no back-end. Por exemplo, se a aplicação espera receber um nome de usuário alfanumérico, ela pode rejeitar ou filtrar qualquer entrada que contenha símbolos como `$`, `{`, `}` ou `[`.

    - Usar consultas parametrizadas: em vez de construir as consultas concatenando strings, é preferível usar consultas parametrizadas, que separam a estrutura da consulta dos valores dos parâmetros. Isso evita que os valores dos parâmetros sejam interpretados como parte da consulta e reduz as chances de NoSQL injection. Por exemplo, em vez de fazer:

    db.users.find({username: req.body.username})
    

    É melhor fazer:

    db.users.find({username: ?}, [req.body.username])
    

    Onde o `?` é um placeholder que será substituído pelo valor do parâmetro `username`.

    - Usar bibliotecas e frameworks confiáveis: muitas vezes, as aplicações web usam bibliotecas e frameworks para facilitar a comunicação com os bancos de dados NoSQL, como por exemplo o Mongoose ou o Lucid-Mongo do ecossistema do AdonisJS. É importante escolher bibliotecas e frameworks que contenham boas práticas de segurança e que ofereçam recursos para prevenir um ataque de injeção. Algumas dessas bibliotecas e frameworks permitem definir esquemas (schemas) para os dados, o que ajuda a validar, sanitizar e tratar os dados de entrada.

    - Aplicar o princípio do menor privilégio: o que significa dar aos usuários e às aplicações apenas os privilégios necessários para realizar suas funções, e nada mais. O que fica em perfeita harmonia com outro princípio: o da Responsabilidade Única do "SOLID".

    Isso limita o impacto potencial de um ataque de NoSQL injection, pois restringe as operações que podem ser executadas no banco de dados. Por exemplo, se uma aplicação só precisa ler dados de uma coleção "X", ela não deve ter permissão para escrever ou apagar os dados dessa coleção.

    Quais são as consequências de um ataque de NoSQL injection?

    Um ataque bem-sucedido pode causar diversos danos aos dados e à aplicação que usa um banco de dados NoSQL. Algumas das consequências possíveis são:

    • Vazamento de informações confidenciais: o atacante pode obter acesso a dados sensíveis, como credenciais, informações pessoais, registros financeiros, etc. Esses dados podem ser usados para fins maliciosos, como roubo de identidade, fraude, chantagem, espionagem industrial, etc.
    • Alteração ou exclusão de dados: o atacante pode modificar ou apagar dados importantes, como históricos, estatísticas, configurações, etc. Isso pode afetar a integridade e a disponibilidade dos dados, causando inconsistências, erros ou, até mesmo, perdas irreversíveis.
    • Execução de código malicioso: como vimos num dos exemplos dados anteriormente, o atacante pode injetar código JavaScript no servidor do banco de dados e executar ações arbitrárias, como criar novos documentos, alterar permissões, instalar malwares, etc. Isso pode comprometer a segurança e o funcionamento do servidor e da aplicação.
    • Escalação de privilégios: o atacante pode usar os dados obtidos por meio do NoSQL injection para acessar outras partes da aplicação ou do sistema que requerem maior nível de autorização. Isso pode ampliar o alcance e o impacto do ataque.

    Como detectar e responder a um ataque de NoSQL injection?

    Para detectar e responder a um ataque de NoSQL injection, é preciso monitorar e analisar as atividades do banco de dados e da aplicação. Algumas das ações recomendadas são:

    • Registrar e revisar os logs: logs são registros das operações realizadas no banco de dados e na aplicação. TUDO que acontece na aplicação deve estar devidamente registrado nessas estruturas. Eles podem fornecer pistas sobre possíveis tentativas ou evidências de NoSQL injection. Por exemplo, se os logs mostram consultas anormais ou resultados inesperados, isso pode indicar um ataque em andamento ou concluído.
    • Usar ferramentas de detecção: existem ferramentas específicas para detectar esses ataques, como o NoSQLMap. Essas ferramentas podem identificar padrões suspeitos nas requisições ou nas respostas do banco de dados e alertar sobre possíveis ameaças. Aqui
    • Realizar auditorias periódicas: as auditorias são processos que verificam a conformidade dos bancos de dados e das aplicações com as normas e as políticas de segurança definidas pelo time de desenvolvimento responsável ou pela empresa como um todo. Em última instância, o seu trabalho é revelar vulnerabilidades ou falhas que possam facilitar ou permitir ataques de injeção. As auditorias devem ser realizadas regularmente e por profissionais qualificados.
    • Isolar e conter o ataque: se um ataque de NoSQL injection for detectado, é preciso agir rapidamente para isolá-lo afim de conter o seu impacto. Isso pode envolver até mesmo desconectar o banco de dados da rede, bloquear o acesso do atacante, etc.
    • Investigar e reportar o ataque: após conter o ataque, é preciso investigar as suas causas, os seus métodos, os seus objetivos e a extensão dos danos causados. Isso pode ajudar a identificar e corrigir as vulnerabilidades que permitiram o ataque, bem como a prevenir ataques futuros. Além disso, é preciso reportar o ataque às autoridades competentes e aos usuários afetados, conforme a legislação e a ética aplicáveis para que sejam tomadas as medidas cabíveis.
    • [Bônus] Manter um backup atualizado regularmente do banco de dados: no cenário mais caótico possível, essa prática pode ajudar a mitigar os danos de uma exclusão da base comum de dados e diminuir os prejuízos incontáveis que perder todas as informações do banco causariam.

    Conclusão

    O NoSQL injection é um tipo de ataques mais comuns a bancos de dados NoSQL e que pode comprometer a segurança e a integridade dos dados armazenados em bancos de dados NoSQL. Para evitar esse ataque, é preciso adotar boas práticas de desenvolvimento, administração e manutenção dos bancos de dados, como validar, sanitizar e tratar os dados de entrada - seja no front ou back-end, usar consultas parametrizadas, bibliotecas e frameworks confiáveis e aplicar o princípio do menor privilégio, além de seguir outras recomendações de segurança, como usar criptografia, autenticação, autorização, controle de acesso, logs, backups, atualizações e testes. Essas medidas podem ajudar a prevenir ou detectar possíveis ataques e minimizar seus danos. Para detectar e responder a um ataque de NoSQL injection, é preciso monitorar e analisar regularmente as atividades do banco de dados e da aplicação, usando ferramentas de detecção, realizando auditorias periódicas, isolando, contendo, investigando e reportando o ataque. Dessa forma, é possível aproveitar as vantagens dos bancos de dados NoSQL sem comprometer a segurança dos dados sob o seu domínio.

    Compartilhe
    Comentários (1)
    Luciano Santos
    Luciano Santos - 27/09/2023 22:26

    Muito bom!!!