JWT é onipresente e frequentemente mal implementado. Este guia lista os 10 erros que a Varredura mais encontra em auth com JWT, cada um com o padrão de correção compatível com app em produção.
JWT é padrão de fato para auth em API em 2026. Também é onde os erros mais recorrentes de segurança acontecem.
Erro 1: Secret hardcoded
const SECRET = "changeme". Aparece em 34% dos apps com JWT auditados pela Varredura em 2026.
Correção: variável de ambiente. Falhar o boot se ausente.
Erro 2: Algorithm none aceito
Se algorithm: HS256 na verificação, mas a lib ainda aceita alg: none no header, atacante forja qualquer token.
Correção: especificar allowlist estrita de algorithms. Rejeitar tudo o mais.
Erro 3: HS256 quando deveria RS256
Se seu backend é distribuído (múltiplos serviços verificando), HS256 é problemático — todo serviço precisa saber o secret.
Correção: RS256 com key pública distribuível. Só o serviço de auth guarda a privada.
Erro 4: Sem expiração
expiresIn ausente. Token vive pra sempre. Se vazar via log, extensão maliciosa ou XSS, é permanente.
Correção: access token com expiração curta (15min). Refresh token separado.
Erro 5: PII sensível no payload
CPF, endereço, saldo no JWT. Payload é decodificável (não é criptografado, é assinado).
Correção: JWT carrega só user_id + roles + expiração. Resto vem do banco.
Erro 6: Sem revogação
Usuário logout, token continua válido. Roubado, continua válido até expirar.
Correção: lista de tokens revogados (Redis com TTL) ou short-lived + refresh.
Erro 7: Refresh token como cookie sem HttpOnly
Se o refresh vive em localStorage ou cookie sem HttpOnly, XSS rouba.
Correção: refresh sempre em cookie HttpOnly + Secure + SameSite=Strict + Path restrito.
Erro 8: Sem rotação de refresh
Refresh token de 30 dias, mesmo valor sempre. Roubou uma vez, tem 30 dias de acesso.
Correção: rotação a cada uso. Antigo revogado quando novo emitido.
Erro 9: Token no query string
GET /api?token=eyJhbGc.... Vaza em log, referrer, cache.
Correção: sempre no header Authorization: Bearer.
Erro 10: Verificação inconsistente entre serviços
Serviço A verifica JWT com uma lib, serviço B com outra. Comportamentos divergem. Bypass possível quando divergem.
Correção: middleware compartilhado. Uma lib única. Teste que confirma comportamento igual.
Roteiro de correção em app rodando
Você não pode invalidar tokens de 10k usuários hoje. Sequência recomendada:
- Corrija verificação (algorithm allowlist, expiração, PII fora do payload).
- Emita novos tokens conforme usuários fazem login.
- Rotacione secret depois que 100% dos tokens antigos expiraram.
- Adicione monitoramento de tentativas de forjar (algorithm none, secret errado).
TL;DR
- 10 erros que a Varredura vê constantemente.
- Correção coordenada, não big bang.
- Access curto + refresh separado.
- Nunca PII no payload.
Auditoria JWT com a Varredura detecta os 10 automaticamente.
Sua app em produção passa por essa análise?
Rode uma varredura autônoma em ~60 segundos. Sem cadastro.