JSON Web Tokens (JWT): estrutura, assinatura e validação
1. Introdução ao JWT e sua Relevância em Segurança
JSON Web Token (JWT) é um padrão aberto (RFC 7519) que define uma forma compacta e autossuficiente de transmitir informações entre partes como um objeto JSON. É amplamente utilizado em autenticação e autorização em aplicações web modernas, especialmente em arquiteturas de microsserviços e APIs RESTful.
É importante entender a diferença entre os padrões relacionados:
- JWT (JSON Web Token): o conceito geral de token codificado em JSON
- JWS (JSON Web Signature): JWT assinado, garantindo integridade e autenticidade
- JWE (JSON Web Encryption): JWT criptografado, garantindo confidencialidade
O uso de JWT sem validação adequada expõe a aplicação a riscos graves como falsificação de tokens, ataques de injeção e vazamento de dados sensíveis.
2. Estrutura do JWT: Header, Payload e Signature
Um JWT é composto por três partes separadas por pontos (.):
header.payload.signature
Header
O header contém metadados sobre o token:
{
"alg": "HS256",
"typ": "JWT"
}
alg: algoritmo de assinatura (HS256, RS256, ES256, etc.)typ: tipo do token (geralmente "JWT")
Payload
O payload contém as claims (declarações) sobre a entidade e dados adicionais:
{
"sub": "1234567890",
"name": "João Silva",
"iat": 1516239022,
"exp": 1516242622,
"admin": true
}
Tipos de claims:
- Registradas: sub, iss, exp, nbf, iat, jti, aud
- Públicas: definidas no IANA JSON Web Token Registry
- Privadas: claims customizadas acordadas entre as partes
Nunca armazene informações sensíveis no payload, pois ele é apenas codificado em base64, não criptografado.
Signature
A assinatura é criada combinando header e payload com uma chave secreta:
HMACSHA256(
base64UrlEncode(header) + "." + base64UrlEncode(payload),
secret
)
3. Algoritmos de Assinatura e Implicações de Segurança
HMAC com SHA-256 (HS256)
Algoritmo simétrico: mesma chave para assinar e verificar.
// Geração do token com HS256
const token = jwt.sign({ userId: 123 }, 'minha-chave-secreta', { algorithm: 'HS256' });
Riscos: se a chave secreta vazar, qualquer um pode forjar tokens válidos.
RSA e ECDSA (RS256, ES256)
Algoritmos assimétricos: par de chaves pública/privada.
// Geração com RS256
const token = jwt.sign({ userId: 123 }, chavePrivada, { algorithm: 'RS256' });
// Verificação
const decoded = jwt.verify(token, chavePublica, { algorithms: ['RS256'] });
Vantagem: apenas quem possui a chave privada pode emitir tokens; qualquer um pode verificar com a chave pública.
Ataque "alg:none"
Uma vulnerabilidade crítica ocorre quando a biblioteca aceita tokens com alg: none:
// Token malicioso
eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJ1c2VySWQiOjF9.
Prevenção: sempre especificar os algoritmos permitidos na verificação:
jwt.verify(token, chavePublica, { algorithms: ['RS256'] });
4. Validação Segura de JWT no Backend
A validação deve seguir uma sequência rigorosa:
// Exemplo de validação segura em Node.js
function validateToken(token) {
try {
const decoded = jwt.verify(token, chavePublica, {
algorithms: ['RS256'],
issuer: 'https://meu-auth-server.com',
audience: 'https://minha-api.com'
});
// Verificações adicionais
if (decoded.exp < Date.now() / 1000) {
throw new Error('Token expirado');
}
if (decoded.nbf && decoded.nbf > Date.now() / 1000) {
throw new Error('Token não está ativo ainda');
}
return decoded;
} catch (error) {
// Log do erro sem expor detalhes sensíveis
console.error('Token inválido:', error.message);
return null;
}
}
Validações essenciais:
- exp: expiration time
- nbf: not before
- iss: issuer (emissor)
- aud: audience (público-alvo)
- iat: issued at (emitido em)
Cuidados com bibliotecas: algumas bibliotecas podem ter vulnerabilidades de desserialização insegura. Sempre use versões atualizadas e mantenha dependências auditadas.
5. Ciclo de Vida do Token: Emissão, Renovação e Revogação
Geração Segura
// Geração com claims essenciais
const token = jwt.sign(
{
sub: user.id,
iat: Math.floor(Date.now() / 1000),
exp: Math.floor(Date.now() / 1000) + (60 * 15), // 15 minutos
jti: uuid.v4(), // ID único do token
iss: 'https://auth.meudominio.com',
aud: 'https://api.meudominio.com'
},
chavePrivada,
{ algorithm: 'RS256' }
);
Estratégia de Tokens Duplos
- Access token: curta duração (15 minutos), enviado em cada requisição
- Refresh token: longa duração (7 dias), usado apenas para obter novos access tokens
// Fluxo de renovação
POST /auth/refresh
{
"refreshToken": "eyJhbGciOiJSUzI1NiIs..."
}
Revogação
- Blacklists: armazenar tokens revogados (jti) em Redis/banco
- Short expiration: minimizar o impacto de tokens comprometidos
- Token rotation: invalidar refresh token ao usar, emitindo um novo
6. Boas Práticas de Armazenamento e Transmissão
Onde Armazenar no Cliente
| Método | Segurança | Recomendação |
|---|---|---|
| localStorage | Vulnerável a XSS | Evitar para tokens sensíveis |
| Session cookies (HttpOnly, Secure, SameSite) | Mais seguro | Preferível para access tokens |
// Configuração segura de cookie
Set-Cookie: access_token=eyJ...; HttpOnly; Secure; SameSite=Strict; Path=/api; Max-Age=900
Proteção contra XSS e CSRF
- XSS: usar cookies HttpOnly impede acesso via JavaScript malicioso
- CSRF: usar SameSite=Strict/Lax e tokens anti-CSRF
Informações Sensíveis
Nunca inclua no payload:
- Senhas
- Números de cartão de crédito
- Dados biométricos
- Informações pessoais identificáveis desnecessárias
7. Monitoramento e Prevenção de Ataques Comuns
Detecção de Tokens Manipulados
// Log de eventos de token
{
"event": "token_validation_failed",
"reason": "signature_mismatch",
"jti": "abc-123",
"timestamp": "2024-01-15T10:30:00Z",
"ip": "192.168.1.100"
}
Proteção contra Replay
Use jti (JWT ID) único e armazene tokens já utilizados:
// Verificação de nonce
if (tokenUsado.includes(decoded.jti)) {
throw new Error('Token já utilizado');
}
Prevenção de Força Bruta
- Rate limiting nas rotas de autenticação
- Monitoramento de tentativas de validação falhas
- Bloqueio temporário após múltiplas falhas
Referências
- RFC 7519 - JSON Web Token (JWT) — Especificação oficial do padrão JWT pela IETF
- JWT.io - JSON Web Token Debugger — Ferramenta interativa para decodificar, verificar e gerar JWTs
- Auth0 - JSON Web Token Handbook — Guia completo sobre implementação segura de JWT
- OWASP - JSON Web Token Cheat Sheet — Boas práticas de segurança para JWT pela OWASP
- JWT - Best Practices for Token-Based Authentication — RFC com recomendações de segurança para implementações JWT
- Node.js jsonwebtoken Documentation — Documentação oficial da biblioteca mais utilizada para JWT em Node.js