Como prevenir vulnerabilidades de injeção de logs em aplicações JavaScript e Node.js
26 de setembro de 2024
0 minutos de leituraEm muitas aplicações corporativas padrão, o registro consistente de logs atende a diversas finalidades. Ele ajuda as empresas a identificar e corrigir erros, oferece insights analíticos valiosos e permite testar novas soluções. No entanto, isso também faz da injeção de logs uma das formas mais comuns de hackers sequestrarem aplicações ou até mesmo obterem acesso a informações confidenciais de usuários. Vulnerabilidades na forma como as aplicações registram dados podem permitir que invasores insiram código malicioso nos logs, comprometendo a integridade e a confidencialidade da sua aplicação.
Neste artigo, você vai conhecer especificamente as vulnerabilidades de injeção de logs em Node.js. Vai descobrir como esses ataques funcionam e aprender maneiras eficazes de evitá-los.
O que é uma vulnerabilidade de injeção de logs?
Para registrar informações, algumas aplicações gravam os logs em um arquivo externo ou usam uma API externa para enviá-los. A injeção de logs ocorre quando um invasor manipula dados de entrada para inserir código malicioso nos logs da aplicação. Em geral, esses logs são usados para depuração, monitoramento e auditoria.
Quando ocorre uma injeção de logs, o invasor pode poluir os logs ou até mesmo executar código no contexto da aplicação, o que leva a diversos riscos de segurança.
Exemplo de uma aplicação Node.js vulnerável
Imagine uma aplicação Node.js simples que usa o framework web Express para registrar dados fornecidos pelo usuário sem validação ou sanitização adequada. O trecho de código a seguir ilustra essa vulnerabilidade:
Quando o servidor estiver no ar e funcionando localmente, você poderá fazer uma requisição GET usando ferramentas de teste de API, como o Insomnia, para verificar se tudo está funcionando como esperado. Neste caso, você pretende registrar o nome de usuário de um formulário e verificar como ficam os logs do servidor. Adicione os dados no formato esperado pelo servidor e envie a requisição. Você receberá um 200 OK e uma mensagem dizendo: "Data logged successfully.":

Se você conferir os logs no servidor, verá que tudo parece estar sendo registrado como esperado. Como você adicionou o valor charlie aos parâmetros de dados, o log mostra INFO: charlie sendo registrado no servidor:

Uma forma de alguém mal-intencionado explorar a maneira como essa aplicação registra dados é inserir logs falsos usando o parâmetro data. Neste exemplo, bastaria adicionar um texto extra à consulta:


Por exemplo, alguém mal-intencionado pode adicionar INFO: User deleted como um log falso. Ao encontrar esse registro, a equipe de desenvolvimento pode ser induzida ao erro e gastar tempo e recursos tentando descobrir por que a aplicação está excluindo usuários quando alguém envia um nome de usuário — tudo porque um invasor decidiu inserir caracteres adicionais em um formulário de entrada.
Embora seja simplista, este exemplo ajuda você a entender o que são injeções de logs em geral. Outros tipos de injeção podem incluir a adição de logs falsos de erros ou de informações de usuários, simplesmente modificando a mensagem do log ou, pior ainda, inserindo injeções de comandos que permitiriam aos invasores manipular dados internos diretamente.
Como prevenir vulnerabilidades de injeção de logs em Node.js
Para reduzir as vulnerabilidades de injeção de logs nas suas aplicações Node.js, considere adotar algumas destas práticas comuns:
Sanitize as entradas do usuário
Na maioria dos casos, as entradas do usuário devem ser validadas e sanitizadas antes de serem registradas. Isso significa verificar cuidadosamente tudo o que será registrado para excluir caracteres que possam ser confundidos com outra entrada de log e/ou permitir apenas os caracteres apropriados.
No exemplo anterior, uma forma de sanitizar os logs seria incluir uma expressão regular que filtre e permita apenas letras do alfabeto. Assim, caracteres especiais ou números não seriam adicionados ao log:

Uma ressalva importante: escolher a forma certa de sanitizar dados pode ser complicado. Neste exemplo, o nome de usuário de quem usar números (por exemplo, 123) será alterado nos logs.
Embora a sanitização das entradas possa ajudar a identificar logs maliciosos, as contrapartidas exigem que os desenvolvedores tenham cuidado extra com o que filtram e como fazem isso. Por exemplo, escrever expressões regulares incorretamente pode resultar em vulnerabilidades ReDOS que paralisam aplicações Node.js. Usar pacotes npm de terceiros, como validator.js, é uma boa opção para não reinventar a roda, mas mantenha essas dependências sempre atualizadas.
Tenha cuidado com o que você registra
Cada aplicação é única. Nenhum padrão de registro de logs atende a todas as necessidades que podem surgir em cada aplicação. É importante pensar nas informações que você precisa registrar e em quem vai consultá-las.
Os logs no nível DEBUG podem ajudar os desenvolvedores a rastrear o que acontece na aplicação e como o usuário navega de um componente para outro ou como as informações fluem de uma origem para outra. Já os logs nos níveis WARN ou ERROR ajudam as equipes de engenharia a identificar possíveis bugs com antecedência e entender o que causa falhas ou mau funcionamento na aplicação. O segredo é registrar apenas o necessário, nada além disso, e considerar o que aconteceria se invasores obtivessem acesso aos seus logs.
Como explica este artigo da Snyk sobre vulnerabilidades de logging, enviar informações confidenciais para um serviço externo de logs pode expor dados a invasores. Em geral, é recomendável evitar o registro de informações confidenciais ou sensíveis, como senhas, chaves de API ou dados pessoais. Se precisar registrá-las, implemente controles de acesso adequados e considere usar variáveis de ambiente (como no GitHub Actions) e sistemas de gerenciamento de chaves para gerenciar dados de configuração confidenciais com segurança.
Além de pensar no que você registra, é preciso considerar como faz isso. O logging estruturado pode organizar melhor os dados registrados, facilitando sua identificação pelos desenvolvedores. Por exemplo, em vez de registrar diretamente os dados do usuário como uma string, como no exemplo anterior, você pode usar um objeto JSON para identificar de forma mais clara o que está sendo registrado:
Mais importante ainda, estruturar os logs dessa forma pode dificultar a injeção de registros por invasores, já que eles também precisariam manipular várias propriedades do objeto de log (por exemplo, action ou time). Se não fizerem isso, podem acabar revelando o que estão tentando fazer:

Embora este exemplo de registro de um objeto JSON seja simplista, existem bibliotecas de logging (que veremos a seguir) que oferecem logging estruturado como uma alternativa útil ao tradicional console.log.
Use uma biblioteca de logging em vez de console.log
Muitas bibliotecas de logging oferecem mais controle e segurança sobre as saídas de log do que console.log, pois normalmente incluem recursos integrados de sanitização e filtragem para evitar ataques de injeção de logs. Elas também permitem que os desenvolvedores controlem quais logs aparecem em cada ambiente (teste ou produção), escolham para onde os logs serão enviados (arquivo local, banco de dados e/ou API de terceiros) e configurem os logs para facilitar o rastreamento.
Uma biblioteca que recomendamos é o pino, um pacote bem mantido e, de modo geral, confiável, sem vulnerabilidades de segurança conhecidas.
O Pino é altamente otimizado para desempenho e pode ser configurado para incluir timestamps em cada registro de log. Ele oferece suporte a logging estruturado e aos níveis padrão de log do sistema. Essa complexidade e estrutura adicionais podem reforçar a segurança e reduzir a probabilidade de os logs serem comprometidos por invasores.
Use a extensão Snyk para IDE no VS Code para detectar vulnerabilidades
A Snyk oferece uma extensão gratuita para IDE do Visual Studio Code (VS Code) que ajuda a detectar vulnerabilidades de injeção de logs (entre outras) no seu código Node.js. Veja como configurá-la:
Acesse a guia Extensions no VS Code e pesquise "Snyk" para encontrar a extensão "Snyk Security - Code, Open Source Dependencies, Iac Configurations". Clique em Install:

Após a instalação, a Snyk solicitará que você autentique sua conta conectando-a à IDE. Clique em Connect VS Code with Snyk. Uma página externa da Snyk será aberta para pedir sua permissão de conexão. Nela, clique em Authenticate.
Depois de autenticar, clique em Scan para analisar seu código em busca de vulnerabilidades. Você também pode configurar a extensão conforme necessário:

A extensão Snyk para IDE analisa automaticamente seu código em busca de vulnerabilidades de injeção de logs. Além disso, durante a análise, a Snyk destaca outros possíveis problemas de segurança no seu código, como segredos codificados diretamente ou vulnerabilidades de path traversal, e oferece insights e recomendações práticas para ajudar você a proteger sua aplicação.
Comece a usar o Snyk gratuitamente
Não é necessário informar um cartão de crédito.
Crie uma conta com Bitbucket e veja mais opções
Ao usar o Snyk, você concorda em cumprir nossas políticas, incluindo os Termos de Serviço e a Política de Privacidade.



