alltools.one
Security
2025-06-12
8 min
alltools.one Team
JWTSecurityAuthenticationAPIWeb Security

Segurança de JSON Web Tokens: Vulnerabilidades Comuns e Correções

Os JWTs são o padrão de fato para autenticação de APIs, mas sua aparente simplicidade esconde armadilhas reais de segurança. JWTs mal configurados já levaram a bypasses de autenticação, escalação de privilégios e vazamentos de dados. Este guia abrange as vulnerabilidades mais críticas e como preveni-las.

Recapitulação da Estrutura JWT

Um JWT consiste em três partes codificadas em Base64URL separadas por pontos:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.signature
  • Header: Algoritmo e tipo do token
  • Payload: Claims (dados do usuário, expiração, etc.)
  • Signature: Verificação criptográfica

Inspecione a estrutura de JWTs com nosso Codificador/Decodificador JWT.

Para uma compreensão fundamental da estrutura JWT, veja nosso guia JWT Tokens Explicado.

Vulnerabilidades Críticas

1. Ataque de Confusão de Algoritmo

A vulnerabilidade JWT mais perigosa. Se um servidor aceita o header alg do token sem validação, um invasor pode:

Ataque: Alterar o algoritmo de RS256 (assimétrico) para HS256 (simétrico) e assinar o token forjado com a chave pública do servidor:

// Token forjado pelo invasor
header: { "alg": "HS256", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
// Assinado com a chave PÚBLICA do servidor como segredo HMAC

Se o servidor verifica tokens HS256 usando a chave pública como segredo, o token forjado passa na verificação.

Correção: Sempre especifique o algoritmo esperado explicitamente:

// ERRADO - aceita qualquer algoritmo que o token especifique
jwt.verify(token, key);

// CORRETO - forçar algoritmo específico
jwt.verify(token, key, { algorithms: ['RS256'] });

2. Ataque do Algoritmo None

Algumas bibliotecas aceitam "alg": "none" — um token sem assinatura:

// Token forjado sem assinatura
header: { "alg": "none", "typ": "JWT" }
payload: { "sub": "admin", "role": "superadmin" }
signature: ""  // vazio

Correção: Nunca permita o algoritmo none em produção. Coloque explicitamente em uma lista de permitidos os algoritmos aceitos.

3. Segredos de Assinatura Fracos

JWTs baseados em HMAC (HS256/HS384/HS512) são tão fortes quanto o segredo:

// PÉSSIMO - pode ser quebrado por força bruta em segundos
secret = "password123"

// FRACO - vulnerável a ataque de dicionário
secret = "my-jwt-secret"

// FORTE - 256+ bits de aleatoriedade
secret = "a3f2b8c9d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0"

Correção: Use pelo menos 256 bits de aleatoriedade criptográfica para segredos HMAC. Melhor ainda, use chaves assimétricas (RS256, ES256) onde a chave de assinatura nunca precisa ser compartilhada.

4. Expiração Ausente

Tokens sem expiração nunca expiram — um token roubado concede acesso permanente:

// ERRADO - sem expiração
{ "sub": "user123", "role": "admin" }

// CORRETO - expiração curta
{
  "sub": "user123",
  "role": "admin",
  "exp": 1705312800,
  "iat": 1705309200,
  "nbf": 1705309200
}

Melhor prática: Tokens de acesso expiram em 15-60 minutos. Use refresh tokens (armazenados com segurança) para sessões longas.

5. Dados Sensíveis no Payload

Payloads de JWT são codificados em Base64URL, não criptografados. Qualquer pessoa pode decodificá-los:

echo "eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ" | base64 -d
# {"sub":"123","role":"admin"}

Nunca inclua: Senhas, chaves de API, números de cartão de crédito, dados pessoais (CPF, registros médicos) ou qualquer segredo nos payloads JWT.

6. Armazenamento de Token (XSS vs CSRF)

ArmazenamentoVulnerável a XSSVulnerável a CSRF
localStorageSimNão
Cookie (sem flags)SimSim
Cookie HttpOnlyNãoSim
Cookie HttpOnly + SameSiteNãoNão

Recomendado: Armazene JWTs em cookies HttpOnly, Secure, SameSite=Strict. Isso impede acesso por JavaScript (defesa contra XSS) e requisições cross-site (defesa contra CSRF).

Set-Cookie: token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/; Max-Age=3600

Checklist de Segurança

  1. Especifique explicitamente os algoritmos — nunca aceite do header do token
  2. Rejeite o algoritmo none — sempre exija uma assinatura
  3. Use segredos fortes — 256+ bits para HMAC, 2048+ bits para RSA
  4. Defina expiração curta — 15-60 minutos para tokens de acesso
  5. Valide todas as claimsexp, iss, aud, nbf
  6. Armazene em cookies HttpOnly — não em localStorage
  7. Rotacione segredos periodicamente — planeje a rotação de chaves
  8. Nunca armazene dados sensíveis no payload
  9. Use chaves assimétricas para sistemas distribuídos (RS256 ou ES256)
  10. Implemente revogação de tokens — blacklist ou expiração curta + refresh tokens

Assinatura Assimétrica vs Simétrica

AspectoHS256 (Simétrico)RS256 (Assimétrico)
ChaveSegredo compartilhadoPar de chaves privada/pública
Quem pode assinarQualquer um com o segredoApenas o detentor da chave privada
Quem pode verificarQualquer um com o segredoQualquer um com a chave pública
Distribuição de chavesSegredo deve ser compartilhado com segurançaApenas a chave pública é compartilhada
PerformanceMais rápidoMais lento
Ideal paraServiço únicoMicrosserviços, sistemas distribuídos

Recomendação: Use ES256 (ECDSA) para novas aplicações — oferece segurança assimétrica com performance próxima ao HMAC.

Estratégias de Revogação de Token

JWTs são stateless por design — não há forma nativa de revogá-los. Estratégias:

  1. Expiração curta: Se os tokens expiram em 15 minutos, a janela de um token roubado é limitada
  2. Rotação de refresh token: Emita um novo refresh token a cada uso; se um refresh token for usado duas vezes, revogue todos os tokens
  3. Blacklist: Armazene IDs de tokens revogados (claims jti) e verifique a cada requisição
  4. Versionamento de token: Inclua um número de versão nas claims; incremente a versão do usuário ao fazer logout

Perguntas Frequentes

Devo usar JWT ou cookies de sessão para autenticação?

Cookies de sessão são mais simples e mais seguros para aplicações web tradicionais — o servidor controla o ciclo de vida da sessão e a revogação é instantânea. JWTs são melhores para APIs stateless, microsserviços e aplicativos móveis onde o armazenamento de sessão no servidor é impraticável. Se escolher JWTs, implemente as medidas de segurança deste guia.

Qual é o tempo ideal de expiração de JWT?

Para tokens de acesso: 15-60 minutos. Mais curto é mais seguro, mas requer renovação mais frequente. Para refresh tokens: 1-30 dias, armazenados em cookies HttpOnly. Para tokens de uso único (verificação de email, redefinição de senha): 1-24 horas.

Recursos Relacionados

Published on 2025-06-12
JSON Web Token Security: Common Vulnerabilities and Fixes | alltools.one