Como proteger uma API REST?
27 de junho de 2024
0 minutos de leitura
Como desenvolvedores, muitas vezes trabalhamos com APIs REST ao integrar sistemas de terceiros ou conectar sistemas de front-end e back-end no trabalho. As APIs — e, em particular, as APIs REST — são fundamentais para as aplicações web modernas, pois permitem criar, ler, atualizar e excluir dados por HTTP. No entanto, como qualquer tecnologia, elas também trazem seus próprios desafios de segurança. Vamos analisar esses desafios e entender como proteger aplicações que usam APIs REST.
O que é uma API REST?
As APIs REST (transferência representacional de estado) são um conjunto de convenções para projetar aplicações em rede. Elas usam protocolos HTTP para enviar e receber dados e podem ser usadas com qualquer linguagem de programação capaz de enviar solicitações HTTP. Isso as torna extremamente versáteis e muito usadas no desenvolvimento web.
No entanto, essa versatilidade também as torna alvo de ameaças cibernéticas. Por isso, você deve sempre priorizar o desenvolvimento de software seguro, por exemplo, implementando os controles proativos do OWASP Top 10. Sem as medidas de segurança adequadas, as APIs REST podem expor dados confidenciais ou até servir de porta de entrada para que invasores comprometam seu sistema.
Ameaças comuns à segurança de APIs REST
Há várias ameaças comuns à segurança de APIs REST que os desenvolvedores devem conhecer:
Ataques de injeção: acontecem quando um invasor envia dados maliciosos como parte de um comando ou consulta, induzindo o interpretador a executar comandos não previstos ou acessar dados sem autorização. Por exemplo, um ataque de injeção de SQL pode manipular as consultas ao banco de dados da sua API, causando vazamentos ou alterações não autorizadas de dados.
Falhas de autenticação: se os mecanismos de autenticação da sua API forem implementados incorretamente, invasores poderão se passar por outros usuários ou até obter privilégios administrativos. Foi o que aconteceu na violação de dados do Reddit em 2018, quando hackers conseguiram contornar a autenticação de dois fatores baseada em SMS.
Exposição de dados confidenciais: as APIs costumam lidar com dados confidenciais, como credenciais de usuários ou informações pessoais. Se esses dados não forem protegidos adequadamente, poderão ser interceptados ou vazados, causando graves violações de privacidade.
Ausência de limitação de taxa: sem limitar a taxa de solicitações, sua API fica vulnerável a ataques de força bruta, nos quais um invasor faz várias tentativas para adivinhar credenciais de usuários ou sobrecarregar seu sistema. Esse foi um dos principais fatores do ataque à Dyn em 2016, que derrubou grandes sites como Twitter e Netflix. A limitação de taxa costuma ser implementada como parte do middleware e é considerada uma boa prática para proteger gateways de API.
Dependências inseguras: se sua API depende de bibliotecas ou frameworks de terceiros com vulnerabilidades conhecidas, os invasores podem explorá-las. Esse é um problema comum em software de código aberto, como ocorreu na violação de dados da Equifax em 2017, quando uma vulnerabilidade no Apache Struts foi explorada.
Você pode reduzir essas ameaças seguindo as boas práticas de segurança para APIs REST, como usar técnicas de programação segura, implementar mecanismos robustos de autenticação e autorização, criptografar dados confidenciais e usar ferramentas como Snyk Code e Snyk Open Source para detectar e corrigir vulnerabilidades no seu código e nas dependências.
Nos próximos capítulos, vamos explorar essas boas práticas e mostrar como você pode implementá-las para proteger suas aplicações que usam APIs REST.
1. Implemente mecanismos robustos de autenticação e autorização
Ao proteger uma API REST, implementar mecanismos robustos de autenticação e autorização é a primeira linha de defesa. Isso garante que somente usuários autenticados e autorizados possam acessar os endpoints da API.
A autenticação segura é o processo de confirmar se um usuário é quem diz ser. Para proteger uma API REST, é essencial garantir que o processo de autenticação seja seguro e impeça acessos não autorizados. Por exemplo, em 2019, uma violação de dados no Facebook expôs as informações pessoais de quase 50 milhões de usuários. A causa foi um problema no mecanismo de autenticação, o que destaca a importância de uma autenticação segura.
O Snyk Code pode ajudar você a detectar possíveis vulnerabilidades de autenticação na sua base de código, como credenciais codificadas diretamente ou ausência de limitação de taxa, que podem levar a ataques de força bruta.
Como usar OAuth 2.0 e JSON Web Tokens (JWT)
OAuth 2.0 é um protocolo que permite que um usuário autorize um site ou aplicativo de terceiros a acessar suas informações sem compartilhar suas credenciais. Ele é amplamente usado por sua escalabilidade e simplicidade.
No contexto da autenticação, JSON Web Tokens (JWT) são um mecanismo popular para a troca segura de informações entre partes na forma de um objeto JSON. As informações contidas em um JWT podem ser verificadas e consideradas confiáveis porque são assinadas digitalmente.
Veja um exemplo de como usar JWT para autenticação em uma API REST com Node.js:
Boas práticas para gerenciar tokens de acesso
Os tokens de acesso são as chaves da sua API e precisam ser gerenciados com segurança. Confira algumas boas práticas:
Expiração do token: os tokens de acesso devem ter uma duração curta. Assim, o impacto será menor caso um token seja comprometido.
Armazenamento do token: evite armazenar tokens de acesso no armazenamento local, pois invasores podem acessá-los facilmente se a aplicação tiver uma vulnerabilidade de cross-site scripting (XSS). Em vez disso, use mecanismos de armazenamento seguros, como cookies HTTP-only com propriedades de segurança habilitadas (SameSite, Secure e HttpOnly, entre outras boas práticas).
Transmissão do token: sempre transmita tokens por canais seguros. Use HTTPS em vez de HTTP para evitar ataques do tipo man-in-the-middle.
O Snyk Open Source pode ajudar você a detectar vulnerabilidades nas dependências de código aberto usadas para gerenciar tokens, garantindo que seus tokens de acesso sejam gerenciados por uma biblioteca sem vulnerabilidades de segurança conhecidas. Para saber mais sobre segurança de aplicações e se antecipar às ameaças, crie uma conta gratuita na Snyk.
2. Proteja os dados em trânsito e em repouso
Proteger os dados, tanto em trânsito quanto em repouso, é essencial para proteger uma API REST. Nesta seção, você encontrará boas práticas para proteger dados em trânsito e em repouso.
HTTPS (Hypertext Transfer Protocol Secure) é uma medida de segurança essencial para qualquer API. Ele garante que os dados transferidos entre o cliente e o servidor sejam criptografados e não possam ser interceptados por invasores.
A maioria dos provedores de nuvem e serviços de hospedagem oferece um certificado SSL gratuito, que você pode usar para habilitar HTTPS na sua API REST. No entanto, se precisar implementar a terminação SSL no próprio código da aplicação para a comunicação entre microsserviços internos ou por outros motivos, veja um exemplo de como forçar o uso de HTTPS em uma aplicação Flask com a extensão Flask-SSLify do pacote Python:
No trecho de código Python acima, usamos a extensão Flask-SSLify para forçar o uso de HTTPS em uma aplicação Flask. Essa é uma das formas de proteger sua API REST com HTTPS.
Métodos de criptografia de dados
A criptografia de dados é outro aspecto crucial para proteger uma API REST. Ela garante que, mesmo que um invasor consiga acessar seus dados, não poderá lê-los sem a chave de descriptografia.
Um método popular de criptografia de dados é o AES (Advanced Encryption Standard). O AES é um algoritmo de criptografia simétrica amplamente usado por sua segurança e eficiência.
No trecho de código Python acima, usamos a biblioteca PyCryptoDome para criptografar dados com AES, usando uma chave de 128 bits e o modo de operação GCM (Galois/Counter Mode).
Como usar cabeçalhos HTTP para reforçar a segurança
Os cabeçalhos HTTP podem reforçar a segurança da sua API REST. Cabeçalhos como Content Security Policy (CSP) e X-Content-Type-Options ajudam a evitar vulnerabilidades web comuns.
CSP é um cabeçalho de segurança que ajuda a prevenir ataques de cross-site scripting (XSS), controlando os recursos que uma página web pode carregar.
X-Content-Type-Options é outro cabeçalho de segurança que impede a detecção automática do tipo MIME, uma técnica usada por invasores para enganar o navegador e fazê-lo executar scripts maliciosos.
No trecho de código Python acima, definimos os cabeçalhos X-Content-Type-Options e CSP em uma aplicação Flask.
Recomendo muito que você leia sobre como uma Content Security Policy pode prevenir XSS e outras vulnerabilidades.
3. Valide e sanitize os dados de entrada
Uma das etapas mais importantes para proteger uma API REST é validar e sanitizar os dados de entrada. Isso é essencial para prevenir ataques como a injeção de SQL.
A injeção de SQL é uma ameaça comum à segurança que explora vulnerabilidades nos campos de entrada de dados de uma aplicação. Nesse tipo de ataque, um invasor pode manipular consultas SQL inserindo código SQL malicioso nos campos de entrada da aplicação, o que permite acessar ou manipular dados sem autorização. De forma semelhante, ataques de injeção de NoSQL podem ocorrer quando um invasor manipula uma consulta a um banco de dados NoSQL ao inserir código malicioso nos campos de entrada da aplicação.
A equipe de pesquisa de segurança da Snyk já publicou alertas de segurança que identificaram a popular biblioteca ORM Squelize como vulnerável a ataques de injeção de SQL. Isso reforça a importância de validar e sanitizar os dados de entrada e monitorar suas bibliotecas de código aberto em busca de vulnerabilidades (você pode usar o Snyk Open Source gratuitamente para ajudar com isso).
Implementação de técnicas de validação de entrada
Para reduzir esses riscos, é essencial implementar técnicas de validação de entrada. A validação garante que somente dados formatados corretamente entrem no seu sistema. Por exemplo, se a idade de um usuário deve ser um número, o sistema deve rejeitar qualquer entrada que não seja numérica.
Veja um exemplo simples de validação de entrada em JavaScript:
Melhor ainda, você pode usar uma biblioteca como Zod ou Joi para validar entradas de forma mais robusta e fácil de manter. Essas bibliotecas definem um esquema esperado para os dados de entrada e os validam com base nesse esquema. Elas são mais rápidas e confiáveis do que escrever sua própria lógica de validação. Para quem usa TypeScript, Zod é uma ótima opção, pois foi desenvolvido pensando nessa linguagem.
Além de validar as entradas, você também deve sanitizar os dados para neutralizar possíveis efeitos nocivos de entradas maliciosas. A sanitização remove ou modifica dados para evitar que sejam usados de forma prejudicial.
Veja um exemplo simples de sanitização de dados em JavaScript:
No entanto, não exagere na sanitização com RegEx. Ela não é uma solução infalível e pode ser contornada por invasores. Em vez disso, use bibliotecas utilitárias como validator.js, disponível no ecossistema npm, que oferece uma ampla variedade de métodos de validação para diferentes tipos de dados. Ao escrever uma RegEx, você pode deixar passar casos extremos e até introduzir uma vulnerabilidade de segurança conhecida como negação de serviço por expressão regular (ReDoS). A Snyk já publicou uma análise detalhada sobre a popular vulnerabilidade ReDoS do UAParser.js.
Validar e sanitizar manualmente cada dado pode ser trabalhoso. Felizmente, existem ferramentas que automatizam essas tarefas. Uma delas é o Snyk Code, uma solução de teste de segurança estática de aplicações (SAST) que ajuda você a identificar e corrigir vulnerabilidades no código, inclusive as relacionadas à validação e sanitização de entradas.
4. Use dependências seguras
Ao pensar em como proteger uma API REST, é fundamental prestar atenção às dependências usadas pela sua aplicação. Nas seções anteriores, mencionamos várias bibliotecas e frameworks populares que já foram identificados como vulneráveis a ameaças de segurança.
Nesta seção, vamos destacar os possíveis riscos de usar bibliotecas vulneráveis, mostrar como usar o Snyk Open Source para detectá-las e apresentar estratégias para manter suas dependências atualizadas.
Os riscos de usar bibliotecas vulneráveis
As dependências são como os blocos que compõem sua aplicação. Mas, assim como um tijolo frágil pode comprometer a estrutura de um prédio, uma biblioteca vulnerável pode representar sérios riscos de segurança para sua API REST.
Por exemplo, a famosa violação de dados da Equifax, em 2017, foi atribuída a uma vulnerabilidade no Apache Struts, um framework de código aberto para criar aplicações web em Java. A violação expôs os dados pessoais de 147 milhões de pessoas, reforçando a importância fundamental de usar dependências seguras.
No exemplo acima, struts.devMode está definido como true, o que pode expor informações confidenciais e deve ser evitado em ambientes de produção.
O modo de desenvolvimento (devMode) do Apache Struts foi criado para desenvolvimento e depuração. Quando devMode está ativado, o framework oferece registros mais detalhados, relatórios de erros e recursos para recarregar configurações. Esses recursos são úteis durante o desenvolvimento, mas podem expor informações confidenciais e criar vulnerabilidades de segurança se forem ativados em um ambiente de produção.
Por exemplo, ativar devMode pode causar:
A exibição de mensagens de erro detalhadas para os usuários, que podem revelar informações sobre a estrutura da aplicação, a tecnologia usada ou até mesmo linhas de código e caminhos específicos que podem ser explorados.
O recarregamento automático de configurações, que pode ser explorado para alterar o comportamento da aplicação sem precisar reiniciá-la.
Maior consumo de recursos devido ao registro e processamento adicionais, o que pode afetar o desempenho e a estabilidade.
Por isso, uma prática recomendada de segurança é garantir que devMode esteja definido como false em ambientes de produção para reduzir esses riscos.
Use Snyk Open Source para detectar dependências vulneráveis
Para reduzir o risco de usar bibliotecas vulneráveis, é essencial ter um sistema robusto para detectar e gerenciar essas vulnerabilidades. É aí que entra Snyk Open Source.
Snyk Open Source é uma ferramenta que ajuda você a identificar e corrigir vulnerabilidades nas suas dependências de código aberto. Ela oferece um banco de dados abrangente de vulnerabilidades conhecidas e monitora continuamente suas dependências para alertar você sobre novos riscos.
No exemplo acima, o comando snyk test analisa seu projeto em busca de vulnerabilidades e oferece recomendações práticas para corrigi-las. Os resultados da análise são exibidos no terminal (ou no painel da Snyk, se você estiver usando a interface web da Snyk) e incluem detalhes sobre as vulnerabilidades, sua gravidade e as correções sugeridas. Veja um exemplo de saída para uma aplicação Java com Spring que usa uma versão vulnerável do Apache Struts:
Estratégias para manter as dependências atualizadas
Manter suas dependências atualizadas é essencial para proteger sua API REST. Confira algumas estratégias para gerenciá-las com eficiência:
Verifique se há atualizações regularmente: Crie o hábito de verificar as atualizações das suas dependências com frequência. Você pode fazer isso manualmente ou usar ferramentas como a Snyk para automatizar o processo.
Adote uma estratégia de versionamento: Escolha uma estratégia que equilibre a necessidade de usar os recursos mais recentes com a estabilidade da sua aplicação. O versionamento semântico é uma abordagem popular que usa números de versão para indicar o tipo e o impacto das mudanças.
Automatize as atualizações sempre que possível: Automatizar as atualizações das dependências pode poupar bastante tempo e reduzir o risco de erros humanos. Você pode configurar a Snyk para abrir automaticamente pull requests com atualizações e patches seguros.
No exemplo acima, o comando snyk monitor monitora continuamente seu projeto e abre automaticamente pull requests com atualizações e patches seguros. Seguindo essas práticas recomendadas, você evita que suas dependências se tornem o ponto fraco da segurança da sua API REST. Lembre-se: quando o assunto é "como proteger uma API REST", cada detalhe importa, e dependências seguras são uma peça fundamental.
Lembre-se: proteger sua API REST envolve mais do que apenas validar e higienizar os dados de entrada. É um processo contínuo que exige monitoramento e atualizações regulares. Seguindo essas práticas recomendadas e usando ferramentas como a Snyk, você pode melhorar significativamente a segurança da sua API REST.
Pronto para começar a proteger sua API REST? Cadastre-se na Snyk hoje mesmo.



