JWT não torna sua API segura: 5 erros que desenvolvedores ainda cometem
Autenticação não é autorização. Veja cinco erros comuns com JWT, Spring Security e APIs REST — e como evitar exposição de dados entre usuários e empresas.
JWT não torna sua API segura: 5 erros que desenvolvedores ainda cometem
Quando começamos a desenvolver APIs REST, uma das primeiras preocupações é implementar autenticação. No ecossistema Java, por exemplo, é comum utilizar Spring Security e tokens JWT (JSON Web Token) para proteger endpoints.
Mas existe uma diferença importante entre saber quem fez uma requisição e garantir que essa pessoa pode executar determinada operação.
Um JWT válido não significa que o usuário deveria ter acesso a qualquer recurso da aplicação. E é justamente nessa confusão que surgem vulnerabilidades sérias.
Neste post, reuni cinco erros que vale observar ao desenvolver uma API, especialmente quando ela atende vários usuários ou empresas.
1. Validar o token, mas esquecer a autorização do recurso
Imagine uma API de cobranças com o endpoint:
GET /api/cobrancas/150
Authorization: Bearer <token>
O usuário está autenticado, mas a cobrança 150 pertence a outra empresa. Se o backend apenas valida o token e retorna o registro, existe uma falha de autorização conhecida como BOLA (Broken Object Level Authorization).
Esconder o ID no frontend ou trocar um número sequencial por UUID não resolve o problema. A verificação deve acontecer no servidor.
Por exemplo, em vez de buscar a cobrança apenas pelo ID, o repositório pode restringir a consulta ao tenant autorizado:
Optional<Cobranca> findByIdAndTenantId(Long id, Long tenantId);
No serviço, o tenantId precisa vir de um contexto de autenticação confiável, estabelecido pelo backend — nunca de um parâmetro que o cliente possa alterar livremente.
Lição: autenticação responde quem é você?; autorização responde o que você pode acessar?.
2. Confiar no tenant_id enviado pelo frontend
Em um SaaS multi-tenant, várias empresas podem compartilhar a mesma aplicação e, em alguns casos, o mesmo banco de dados.
Uma consulta como esta parece correta:
SELECT id, cliente, valor
FROM cobrancas
WHERE tenant_id = 10;
A pergunta é: quem decidiu que o tenant autorizado é o 10?
Se o frontend puder informar livremente esse valor, um usuário pode tentar substituí-lo pelo identificador de outra empresa.
O backend deve resolver o tenant autorizado a partir da identidade autenticada e dos vínculos validados no servidor. Além disso, filtros de isolamento precisam ser aplicados de maneira consistente em consultas, atualizações, exclusões e tarefas assíncronas.
Lição: isolamento de dados é uma regra de segurança, não apenas uma convenção de consulta SQL.
3. Armazenar tokens sem avaliar os riscos
É comum ver exemplos que salvam o JWT em localStorage:
localStorage.setItem('access_token', token);
Essa abordagem é simples, mas um script malicioso executado por uma vulnerabilidade de XSS pode conseguir ler o token.
Cookies com HttpOnly, Secure e uma política adequada de SameSite reduzem alguns riscos de exposição do token ao JavaScript. Por outro lado, autenticação baseada em cookies também exige avaliar proteção contra CSRF, conforme o fluxo utilizado.
Não existe uma solução universal para todas as arquiteturas. A escolha depende do tipo de cliente, da forma de autenticação e do modelo de ameaças.
Lição: decidir onde guardar credenciais faz parte do desenho de segurança da aplicação.
4. Emitir tokens sem planejar expiração e revogação
Um JWT assinado pode continuar válido até expirar, mesmo depois de o usuário sair da interface, se não houver um mecanismo de revogação aplicável.
Por isso, vale planejar o ciclo de vida da sessão:
- Access tokens com validade curta, adequada ao risco da aplicação.
- Refresh tokens com armazenamento protegido, rotação e possibilidade de revogação.
- Validação de assinatura e dos campos esperados, como
iss,aud,expe, quando aplicável,nbf. - Estratégia para lidar com contas comprometidas, mudanças de permissão e encerramento de sessões.
- Proteção das chaves de assinatura e configuração explícita dos algoritmos aceitos.
Lição: gerar um token é só uma parte do trabalho; administrar a sessão é outra.
5. Achar que esconder botões no frontend protege a API
Imagine que a interface não mostre o botão Excluir usuário para quem não é administrador. Isso melhora a experiência, mas não impede alguém de enviar manualmente:
DELETE /api/usuarios/25
Authorization: Bearer <token>
A API precisa verificar as permissões em cada operação sensível. Com Spring Security, regras como @PreAuthorize podem ajudar, mas a autorização também deve considerar o recurso e seu proprietário.
Por exemplo, ter o papel ADMIN de uma empresa não significa poder excluir usuários de todas as empresas.
Lição: o frontend apresenta as ações disponíveis; o backend aplica as regras de acesso.
Um checklist antes de colocar a API em produção
Antes de publicar uma funcionalidade, eu verificaria:
- O endpoint exige autenticação quando necessário?
- O usuário tem permissão para realizar a ação?
- O recurso pertence ao usuário ou tenant autorizado?
- O servidor valida todos os dados recebidos?
- Tokens, cookies e chaves têm proteção adequada?
- Existem testes tentando acessar recursos de outro usuário ou empresa?
- Logs registram eventos relevantes sem expor tokens ou dados sensíveis?
Conclusão
JWT é útil para transportar declarações assinadas e verificáveis, mas não substitui autorização, isolamento de dados, validação ou monitoramento.
Ao implementar um endpoint, três perguntas ajudam a orientar o desenvolvimento:
- Quem está realizando esta operação?
- Essa pessoa tem permissão para executar a ação?
- Esse recurso pertence ao contexto autorizado?
Uma API segura não é aquela que apenas bloqueia usuários não autenticados. É aquela que garante que cada usuário autenticado acesse somente aquilo que deveria.
Sobre o DevDiary: aqui compartilho estudos, projetos em desenvolvimento, decisões técnicas e o que aprendo ao construir software.
Quer conhecer meus projetos? Acesse meu portfólio. Precisa de um site, sistema ou automação para sua empresa? Conheça a Covalia Software.