ToolDeck

JWT

2 ferramentas

Fundamentos de segurança web

A segurança web é a prática de proteger aplicativos web e APIs de acesso não autorizado, violações de dados e ataques. Os aplicativos modernos usam autenticação, autorização e criptografia para impor limites de segurança.

Os JSON Web Tokens (JWT) são o mecanismo de autenticação sem estado dominante no desenvolvimento web moderno. Entender como os JWTs funcionam — incluindo sua estrutura, algoritmos de assinatura e vulnerabilidades conhecidas — é essencial para construir APIs e aplicativos seguros.

JSON Web Tokens (JWT)

Um JWT é uma forma compacta e segura para URLs de representar afirmações entre duas partes. Consiste em três partes codificadas em Base64url separadas por pontos. Uma das principais vantagens dos JWTs é que podem ser verificados sem consultas ao banco de dados, pois a assinatura cobre todo o token — isso os torna ideais para arquiteturas distribuídas e microsserviços.

As três partes de um JWT

Header

Contém metadados sobre o token: o algoritmo de assinatura (alg) e o tipo de token (typ). É sempre um JSON codificado em Base64url. A escolha do algoritmo declarada aqui afeta diretamente a segurança de todo o token.

Codificado
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Decodificado
{
  "alg": "HS256",
  "typ": "JWT"
}
Payload

Contém as afirmações: declarações sobre o usuário e metadados adicionais. Também é um JSON codificado em Base64url. Qualquer pessoa que interceptar o token pode decodificar e ler este conteúdo — os dados do payload NÃO são criptografados, apenas assinados.

Codificado
eyJzdWIiOiJ1c2VyXzEyMyIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTcxNzIwMDAwMH0
Decodificado
{
  "sub": "user_123",
  "role": "admin",
  "exp": 1717200000
}
Signature

Uma assinatura criptográfica sobre o cabeçalho e payload codificados. Verificar esta assinatura garante que o token não foi adulterado. A chave secreta (HMAC) ou chave privada (RSA/ECDSA) nunca é incluída no próprio token.

Codificado
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Decodificado
HMACSHA256(
  base64url(header) + "." +
  base64url(payload),
  secret
)

Afirmações JWT padrão

A especificação JWT define nomes de afirmações padrão para garantir interoperabilidade entre bibliotecas e serviços diferentes. Além das afirmações registradas abaixo, você pode incluir afirmações privadas (campos customizados), desde que seus nomes não conflitem com os nomes reservados da RFC 7519.

AfirmaçãoNomeDescrição
issIssuerIdentifica o principal que emitiu o token (ex: URL do seu servidor de autenticação)
subSubjectIdentifica o principal que é o assunto do token (ex: ID do usuário)
audAudienceIdentifica os destinatários para os quais o token é destinado (ex: URL da sua API)
expExpirationTimestamp Unix após o qual o token não deve ser aceito para processamento
nbfNot BeforeTimestamp Unix antes do qual o token não deve ser aceito para processamento
iatIssued AtTimestamp Unix em que o token foi emitido — usado para determinar a idade do token
jtiJWT IDIdentificador único para o token, usado para prevenir ataques de replay

Algoritmos de assinatura

O algoritmo de assinatura é declarado no cabeçalho JWT. Escolher o algoritmo certo para o seu caso de uso é crítico para a segurança:

HS256 / HS384 / HS512Simétrico (HMAC)

Usa uma chave secreta compartilhada para assinar e verificar. Simples de implementar mas requer que todos os verificadores conheçam o segredo.

Usar quando: Serviços internos onde você controla todas as partes. Nunca use quando terceiros precisam verificar os tokens.
RS256 / RS384 / RS512Assimétrico (RSA)

Usa uma chave privada para assinar e uma chave pública para verificar. A chave privada nunca sai do servidor de autenticação. Múltiplos serviços podem verificar tokens usando apenas a chave pública, sem precisar compartilhar nenhum segredo.

Usar quando: Arquiteturas de microsserviços, verificação de tokens de terceiros, OAuth2 e OpenID Connect.
ES256 / ES384 / ES512Assimétrico (ECDSA)

Como RSA mas com chaves menores e assinatura mais rápida. Fornece segurança equivalente com melhor desempenho.

Usar quando: Aplicativos móveis e IoT onde o desempenho importa. Alternativa moderna ao RSA.
"alg": "none"Sem assinatura — PERIGOSO

Sem assinatura. Um token com alg:none não tem garantia de integridade e pode ser falsificado por qualquer pessoa.

Usar quando: Nunca usar em produção. Algumas bibliotecas JWT historicamente aceitavam alg:none, o que levou a vulnerabilidades críticas amplamente exploradas.

Fluxos de autenticação

Concessão de senha (direta)
  1. 1.O usuário envia nome de usuário e senha para o endpoint de login
  2. 2.O servidor valida as credenciais contra o banco de dados de usuários
  3. 3.O servidor assina um JWT com as afirmações do usuário e a expiração
  4. 4.O cliente armazena o JWT (localStorage, cookie ou memória)
  5. 5.O cliente envia o JWT no cabeçalho Authorization: Bearer para solicitações subsequentes
Código de autorização + PKCE (OAuth2)
  1. 1.O cliente redireciona o usuário para o servidor de autorização com o desafio de código
  2. 2.O usuário se autentica e autoriza o aplicativo cliente
  3. 3.O servidor de autenticação redireciona de volta com um código de autorização de uso único
  4. 4.O cliente troca código + verificador por tokens de acesso e atualização
  5. 5.O cliente usa o token de acesso para chamadas de API; token de atualização para renovação

Vulnerabilidades JWT comuns

Os JWTs são seguros quando implementados corretamente. Estes são os erros de implementação mais comuns que levam a vulnerabilidades de segurança:

Confusão de algoritmo (alg:none)Crítico

Algumas bibliotecas aceitam tokens com alg:none (sem assinatura). Um invasor pode modificar o payload e definir alg como none para falsificar qualquer JWT. Sempre especifique e valide explicitamente o algoritmo permitido na sua biblioteca.

Confusão HS256 / RS256Crítico

Se uma biblioteca espera verificar RS256 mas aceita HS256, um invasor pode assinar um token usando a chave pública como segredo HMAC. A biblioteca verifica com sucesso sem detectar a fraude. Sempre fixe o algoritmo esperado na configuração da biblioteca.

Validação de expiração ausenteAlto

Um JWT sem afirmação exp, ou código que não verifica exp, permite que tokens sejam usados indefinidamente após o logout ou banimento do usuário. Sempre defina tempos de expiração curtos e valide a afirmação exp em cada requisição.

Dados sensíveis no payloadAlto

Os payloads JWT são codificados em Base64, não criptografados. Qualquer pessoa que interceptar um JWT pode decodificar e ler seu conteúdo. Nunca armazene senhas, números de cartão de crédito ou outros segredos nas afirmações JWT.

Chaves secretas fracas (HS256)Médio

JWTs assinados com HMAC com segredos curtos ou previsíveis podem ser quebrados por força bruta offline. Um invasor que obtém um JWT pode testar bilhões de chaves por segundo. Use segredos criptograficamente aleatórios de pelo menos 256 bits.

Verificação de assinatura ausenteMédio

Aceitar JWTs sem verificar a assinatura confia completamente no payload. Este é um bug crítico que permite que qualquer usuário crie afirmações arbitrárias. Sempre verifique a assinatura antes de confiar em qualquer afirmação.

Perguntas frequentes

Os JWTs são criptografados?

Os JWTs padrão (JWS — JSON Web Signature) são assinados mas NÃO criptografados. O payload é codificado em Base64url, que é trivialmente reversível — qualquer pessoa que obtiver o token pode ler seu conteúdo. O JWE (JSON Web Encryption) oferece criptografia real, mas é muito menos comum na prática.

Por quanto tempo um JWT deve ser válido?

Os tokens de acesso devem ter vida curta: 5–60 minutos é típico. Tokens de longa duração são perigosos porque não podem ser revogados sem uma lista de bloqueio. Use tokens de atualização — com vida mais longa e armazenados com segurança — para obter novos tokens de acesso sem exigir novo login do usuário.

Onde devo armazenar JWTs no navegador?

Cookies HttpOnly são a opção mais segura — são inacessíveis ao JavaScript, prevenindo roubo por XSS. O localStorage é vulnerável a ataques XSS mas evita CSRF. Armazenar em memória (variável JavaScript) é o mais seguro de todos, mas o token não sobrevive a uma atualização de página. Não existe opção perfeita — cada abordagem envolve trocas entre segurança e usabilidade.

Posso revogar um JWT antes de expirar?

Não sem estado no lado do servidor. A natureza sem estado dos JWTs significa que o servidor não pode invalidá-los diretamente. As soluções práticas incluem: tempos de expiração curtos, uma lista de bloqueio de tokens (Redis), tokens de atualização rotativos, ou migrar para tokens opacos de sessão em operações sensíveis.

Qual é a diferença entre JWT e cookies de sessão?

Cookies de sessão armazenam um ID de sessão aleatório; o servidor procura os dados da sessão em cada requisição. Os JWTs são autossuficientes — o servidor valida a assinatura sem consulta ao banco de dados. Os JWTs escalam melhor em múltiplos servidores, mas não podem ser revogados sem infraestrutura adicional.

Quais afirmações devo incluir em um JWT?

O mínimo: sub (ID do usuário), exp (expiração) e iat (emitido em). Adicione iss (emissor) para configurações com múltiplos serviços. Mantenha os payloads pequenos — os JWTs são enviados com cada requisição. Não inclua dados sensíveis nem objetos de perfil volumosos.

RS256 é melhor que HS256?

RS256 (assimétrico) é melhor para a maioria dos sistemas de produção porque apenas o servidor de autenticação precisa da chave privada. Múltiplos serviços podem verificar tokens usando a chave pública sem compartilhar nenhum segredo. HS256 é mais simples de configurar, mas exige que todos os verificadores conheçam o segredo compartilhado — o que aumenta a superfície de ataque.

O que é PKCE e por que é importante?

PKCE (Proof Key for Code Exchange) é uma extensão do fluxo de código de autorização OAuth2 que previne ataques de interceptação de código. É obrigatório para clientes públicos (SPAs, aplicativos móveis) que não podem armazenar com segurança um segredo de cliente.