Como evitar falhas no controle de acesso em aplicações Node.js com Express
Ben Smitthimedhin
22 de maio de 2024
0 minutos de leituraO controle de acesso em aplicações backend Node.js é fundamental para aplicações web criadas com o framework Express. Ele garante que os usuários acessem apenas os dados e recursos para os quais têm autorização. No entanto, quando há falhas no controle de acesso, os usuários podem acessar dados que não deveriam. Isso é especialmente preocupante quando invasores tentam manipular ou roubar dados privados.
É fundamental entender e prevenir vulnerabilidades de controle de acesso, pois o vazamento de dados privados pode ser desastroso para muitas empresas. Neste artigo, você vai conhecer melhor as falhas no controle de acesso em aplicações Node.js e as estratégias para evitar essas vulnerabilidades ao criar aplicações web com o framework Express.
O que é uma falha no controle de acesso?
Controle de acesso é a prática de limitar o que um usuário pode fazer e ver em uma aplicação. Uma falha no controle de acesso ocorre quando há problemas na implementação das regras de controle de acesso da aplicação, permitindo que usuários não autorizados acessem informações confidenciais ou realizem ações restritas.
Por exemplo, se um usuário comum puder visualizar os dados privados de outro usuário, alterar a senha dele ou até mesmo elevar seus privilégios ao nível de administrador por causa de uma falha no controle de acesso, as consequências podem ser catastróficas — desde vazamentos de dados até modificações não autorizadas no sistema.
Na próxima seção, você vai conferir exemplos de código que mostram diferentes tipos de vulnerabilidades no controle de acesso.
Falhas no controle de acesso vertical no middleware do Express
Um tipo de vulnerabilidade no controle de acesso ocorre quando há uma falha ou fragilidade no controle de acesso vertical. Isso acontece quando um usuário comum obtém acesso a recursos de administrador ou outros privilégios que não deveria ter. Assim, esse usuário sobe na hierarquia de privilégios e pode fazer alterações, exclusões ou outras operações administrativas que não deveria poder realizar.
Veja a seguir algumas vulnerabilidades específicas de código que podem levar a falhas no controle de acesso vertical:
Painel de administração desprotegido nas rotas do Express
Um painel de administração desprotegido ocorre quando as rotas que levam a recursos administrativos em uma página web ou servidor não têm nenhum tipo de autorização:
Nesse cenário, qualquer pessoa que fizer uma solicitação GET para a rota /admin receberá automaticamente a mensagem Welcome to the Admin Panel!, independentemente de ter feito login ou de ter as permissões necessárias. O painel /admin está desvinculado da rota /login, quando não deveria estar. Isso é uma forma de falha no controle de acesso.
Painel de administração do Express baseado em parâmetros de consulta
É simples implementar um painel de administração baseado em parâmetros de URL. No entanto, sem nenhum tipo de validação, ele pode ser facilmente manipulado:
Neste exemplo, um usuário que faz uma solicitação GET diretamente para a rota /admin recebe a resposta Access denied. Para contornar essa restrição, basta adicionar ?isAdmin=true à URL. Como qualquer pessoa que acessa o painel de administração pode adicionar esses parâmetros, a mesma vulnerabilidade do primeiro exemplo se repete: um usuário comum consegue obter privilégios de administrador.
Controle de acesso nas rotas do Express por obscuridade
Em teoria, seria possível ocultar a rota do painel de administração, tornando-a difícil de adivinhar, como no middleware de rota do Express a seguir:
Isso pode até dar a impressão de que o painel de administração está mais seguro, mas é uma forma insegura e equivocada de proteger uma aplicação. Invasores podem encontrar uma maneira de acessar o mapa do site e descobrir todos os endpoints disponíveis. Também podem usar técnicas de fuzzing para testar todos os endpoints possíveis e observar as respostas. Outra possibilidade é tentar acessar os arquivos de log para encontrar a URL registrada que permite acessar o painel de administração. Embora pareça uma solução engenhosa, esse método não oferece nenhuma proteção eficaz e acaba perpetuando uma vulnerabilidade no controle de acesso.
Registro de informações em texto simples em aplicações Express
Os desenvolvedores também devem ter cuidado com os mecanismos de registro de logs para evitar a divulgação acidental de informações críticas aos usuários da aplicação. Por exemplo, uma aplicação pode registrar uma ação de login com informações confidenciais sem remover a senha dos dados registrados:
Observe a instrução console.log no final. Quem tiver acesso aos arquivos de log também poderá acessar os dados dos usuários e fazer login como qualquer pessoa com privilégios administrativos. Por isso, é importante registrar apenas as informações necessárias em cada contexto. Além disso, em geral, é recomendável garantir que ninguém registre informações críticas que possam permitir que invasores explorem dados em caso de violação.
Falhas no controle de acesso horizontal no middleware do Express
Problemas no controle de acesso vertical permitem que usuários elevem seus privilégios. Já os problemas no controle de acesso horizontal ocorrem quando um usuário acessa recursos ou dados que pertencem a outros usuários do mesmo nível.
Vamos conferir alguns exemplos de código de vulnerabilidades no controle de acesso horizontal em aplicações web Node.js que usam o framework Express.
ID do usuário em um parâmetro de solicitação enviado a uma rota Express
Uma aplicação que permite que os usuários vejam seu ID em um parâmetro de solicitação pode ser problemática, especialmente se os dados de um usuário puderem ser acessados usando esse mesmo ID nos parâmetros. Isso significa que basta saber os IDs de outras pessoas para acessar os dados delas.
Por exemplo, se seu ID for 123, para acessar as informações da sua conta em um site, você precisaria acessar www.[website name].com/account?userId=123:
Neste exemplo, ao fazer uma solicitação GET para /account com a consulta userId=1, você consegue obter facilmente o objeto accountData de logan@test.com, mesmo que tenha feito login como outra pessoa. Ao fazer a mesma solicitação GET com a consulta userId=2, você obtém o objeto accountData de megan@test.com. Basta usar no parâmetro o ID associado a determinado usuário para que a consulta retorne o objeto accountData
Essa vulnerabilidade de segurança é conhecida como referência direta insegura a objetos (IDOR) e pode ocorrer em Java, Ruby e outras linguagens de programação.
ID imprevisível de usuário em um parâmetro de solicitação que chega ao middleware de uma rota Express
Com base no exemplo anterior, alguém poderia pensar que um controle de acesso bem projetado consiste simplesmente em ocultar o ID do usuário. Por exemplo, um usuário com o ID 1 poderia ter esse ID transformado, por meio de hashing e codificação, em 8a76dh3t na consulta, dificultando o acesso aos dados de outras pessoas:
Neste exemplo, a função obfuscateUserId obtém o ID do usuário da lista de usuários existentes e o oculta. Portanto, para fazer uma solicitação GET à rota /account e obter informações da conta, é necessário conhecer e informar o ID oculto no parâmetro da solicitação (por exemplo, userId=8a76dh3t).
Esse método não usa controles de segurança eficazes e apenas perpetua o problema de falha no controle de acesso. Com tempo e dedicação, invasores ainda podem usar fuzzing para descobrir o ID de usuário oculto correto e obter acesso, causando mais uma falha no controle de acesso.
Usando a ausência de proteções contra CSRF em aplicações Express como vetor de ataque
Por fim, uma forma comum de agentes mal-intencionados explorarem as falhas no controle de acesso da sua aplicação Express é por meio de ataques de falsificação de solicitação entre sites (CSRF). Em resumo, esses ataques criam páginas ou links falsos que induzem você a enviar suas informações. Em seguida, essas informações são anexadas a uma função que envia uma solicitação legítima ao site verdadeiro, onde seus dados ficam acessíveis.
Sem a implementação de uma proteção contra CSRF, todas as aplicações de servidor dos exemplos que você viu podem ser incorporadas a um formulário falso em uma página web. Assim, um usuário insere os dados e os envia para que uma pessoa mal-intencionada os explore.
Como evitar vulnerabilidades de controle de acesso em Node.js
Agora que você viu alguns exemplos de vulnerabilidades no controle de acesso vertical e horizontal, é hora de conhecer estratégias gerais para evitá-las.
Use as versões mais recentes das bibliotecas
Uma forma de garantir que seu controle de acesso siga padrões mais rigorosos é usar pacotes npm confiáveis, mantidos e seguros. No entanto, o Node.js e seu ecossistema de pacotes recebem atualizações frequentes para corrigir vulnerabilidades de segurança. Por isso, também é essencial manter tudo atualizado.
Manter o runtime do Node.js e os pacotes atualizados é fundamental para reduzir o risco de problemas de segurança conhecidos. Uma forma de fazer isso é verificar a integridade do seu arquivo package.json usando o Snyk Advisor, que mostra quais bibliotecas têm vulnerabilidades que precisam ser corrigidas e se algum pacote npm foi descontinuado ou deixou de receber manutenção.
Ao arrastar e soltar um arquivo de exemplo package.json no Snyk Advisor, você verá que há vários pacotes npm potencialmente problemáticos neste projeto:

Analisando mais de perto, o Snyk Advisor mostra que loader não recebe uma nova versão há oito anos e não é muito popular entre os usuários do npm em comparação com outros pacotes. Verificar atualizações regularmente e aplicá-las prontamente — ou até substituir bibliotecas desatualizadas no seu projeto — são boas primeiras medidas para manter seu controle de acesso seguro.
Não confie apenas na ofuscação
Como você viu em alguns exemplos, a segurança por obscuridade não é uma estratégia confiável. Se um invasor conseguir adivinhar como obter acesso (ou encontrar o caminho por meio de fuzzing), sua aplicação não estará segura. Implemente mecanismos adequados de controle de acesso e verificações de autenticação para garantir que somente usuários autorizados acessem dados e recursos confidenciais.
No exemplo anterior, havia uma rota cujo endpoint usava números difíceis de adivinhar:
Na prática, geralmente é mais seguro recorrer ao método comprovado de proteger dados com esquemas de autenticação adequados antes de conceder acesso. Recomendamos usar bibliotecas de login mais seguras, como Passport.js ou AWS Cognito. A seguir, apresentamos um esboço de página de login sem bibliotecas externas, apenas para fins educativos:
Em vez de ocultar a rota do painel de administração, os usuários podem acessar diretamente /login, mas precisam informar o e-mail e a senha corretos no corpo da solicitação para obter acesso ao painel. Assim, você não depende de métodos arriscados de ocultação e tem mais controle sobre as informações e respostas que cada usuário recebe.
Negue o acesso por padrão e conceda permissões granulares
Ao decidir quais usuários devem ter acesso a diferentes tipos de dados na sua aplicação, geralmente é melhor começar do zero. Adote o princípio do menor privilégio: inicialmente, negue o acesso a tudo e conceda acesso a recursos e ações específicos somente quando necessário.
Além disso, implemente um controle de acesso granular que avance gradualmente, garantindo que os usuários só possam realizar as ações para as quais têm autorização explícita. No exemplo anterior, a inclusão de outras funções pode ajudar a tornar os controles ainda mais granulares:
Aqui, os privilégios mais altos são reservados ao “Level 3 panel”, disponível apenas para usuários com a função admin. Outros usuários com a função manager terão acesso ao “Level 2 panel”, que, por exemplo, pode exibir informações sobre cada usuário, mas não inclui um botão de exclusão.
Quem não receber uma função explicitamente verá automaticamente a resposta “Unauthorized access”. Conceder permissões específicas aos usuários e ampliá-las gradualmente, conforme necessário, ajuda a evitar que você conceda privilégios extras a quem não deveria ter acesso a eles.
Faça auditorias e testes completos
Faça auditorias regulares da sua base de código e realize testes de segurança, como análise estática de código, varredura de dependências e revisões de código seguro, para identificar vulnerabilidades de controle de acesso e outros problemas de segurança. Pode ser útil salvar nos favoritos esta lista (ou outra) de possíveis vulnerabilidades de controle de acesso e usá-la para garantir que elas não estejam presentes na sua aplicação. Além disso, adicionar testes unitários à sua aplicação é uma prática padrão para garantir que cada linha de código funcione como esperado.
Ferramentas de varredura automatizada, como testes de segurança estática de aplicações (SAST), devem ser sempre consideradas para ajudar você a identificar problemas de segurança comuns. Com a extensão do Snyk para o VS Code, você recebe feedback rápido com verificações de segurança sempre que salva seus arquivos JavaScript, incluindo recomendações automatizadas de correção.
Use a extensão do Snyk para Visual Studio Code
Uma ferramenta poderosa que merece destaque é o Snyk. Embora o Snyk ofereça várias ferramentas para proteger sua aplicação, a extensão do Visual Studio (VS) Code, em particular, pode ajudar você a detectar e corrigir vulnerabilidades de controle de acesso quebrado no código Node.js enquanto escreve.
Veja como configurar a extensão do Snyk e usá-la com eficiência:
Acesse a guia Extensões no VS Code e pesquise por "Snyk" para encontrar a extensão Snyk Security - Code, Open Source Dependencies, IaC Configurations. Clique em Instalar:

Depois da instalação, o Snyk solicitará que você autentique sua conta conectando-se ao IDE. Clique em Connect VS Code with Snyk. Uma página externa do Snyk será aberta, solicitando sua permissão para conectar-se. Nessa página, clique em Authenticate.
Depois de se autenticar, clique em Verificar para procurar vulnerabilidades no seu código. Você também pode configurar a extensão conforme necessário.
Usando os exemplos anteriores das rotas /admin, /login e /account, o Snyk conseguiu detectar doze vulnerabilidades de segurança. Além disso, o Snyk também verifica se há possíveis problemas de qualidade do código, configuração e segurança de código aberto na sua aplicação ou nas bibliotecas que fazem parte dela:


A extensão do Snyk verifica seu código em busca de vulnerabilidades de segurança conhecidas, incluindo as relacionadas ao controle de acesso. Ela fornece feedback em tempo real e sugere correções para os problemas identificados. Com essa extensão, você pode detectar e corrigir vulnerabilidades de controle de acesso quebrado antes que elas cheguem ao ambiente de produção.
Além disso, o Snyk oferece várias ferramentas de verificação de código que você pode usar. Assim como a extensão do VS Code, essas ferramentas foram desenvolvidas para encontrar problemas de segurança no seu código enquanto você escreve, tornando-se essenciais para identificar e corrigir problemas de controle de acesso em tempo real.
Conclusão
Neste artigo, você aprendeu sobre o controle de acesso quebrado no Node.js, um problema crítico de segurança que pode levar ao acesso não autorizado a dados e privilégios em aplicações desenvolvidas com o framework Express. Dos endpoints Express de painéis administrativos desprotegidos a IDs de usuário imprevisíveis em parâmetros de solicitação, os exemplos mostram os riscos potenciais do controle de acesso quebrado.
Para evitar vulnerabilidades de controle de acesso quebrado nas suas aplicações Node.js, você pode adotar algumas estratégias importantes: usar as versões mais recentes das bibliotecas, evitar métodos de segurança por obscuridade, aplicar o princípio do menor privilégio, realizar auditorias e testes completos e aproveitar ferramentas como a extensão do Snyk para Visual Studio Code. Em conjunto, essas medidas podem reforçar significativamente a segurança da sua aplicação. Lembre-se: criar e manter uma aplicação segura é um processo contínuo. A vigilância é essencial para preservar a integridade das suas aplicações e dos seus dados.
Use o Snyk e comece a corrigir problemas de segurança hoje mesmo!


