Guia · Segurança · JWT

JWT: como ler um token e o que ele não garante

Um JWT parece um texto embaralhado, mas qualquer pessoa consegue ler o que há dentro dele. Veja como ele é montado, o que significa cada claim comum e por que conseguir ler o conteúdo não prova que o token é verdadeiro.

As três partes do token

O formato mais comum de JWT é o JWS em serialização compacta, definido na RFC 7515: três blocos de texto separados por ponto, na forma cabeçalho.conteúdo.assinatura. Cada bloco é codificado em Base64URL. A RFC 7519 informa que o número de partes depende da representação: um JWT criptografado (JWE) tem cinco partes. Este guia trata do caso de três partes, que é o que você encontra na maioria dos cabeçalhos Authorization: Bearer.

O que é Base64URL

É o Base64 com dois ajustes para poder viajar em URLs e cabeçalhos: o + vira -, o / vira _ e os = de preenchimento no fim são omitidos. A RFC 7515 define Base64url como a variante da RFC 4648 sem o preenchimento.

Teste real: o JSON {"a":"é>>?"} em Base64 comum vira eyJhIjoiw6k+Pj8ifQ==. Em Base64URL vira eyJhIjoiw6k-Pj8ifQ, com - no lugar do + e sem os dois = finais. Colar um trecho de JWT em um decodificador de Base64 comum pode falhar justamente por isso. Para essa conversão, use a ferramenta de Base64, que aceita as duas variantes.

Importante: Base64URL é só uma forma de escrever bytes. Não há chave, não há segredo. Quem tem o token tem o conteúdo.

Exemplo: lendo um token fictício

Este token foi montado para o guia, com dados inventados e uma assinatura sem valor:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGguZXhlbXBsby5jb20uYnIiLCJzdWIiOiJ1c2VyLTEwNDIiLCJhdWQiOiJhcGktcGVkaWRvcyIsImlhdCI6MTc5MzgzNjgwMCwibmJmIjoxNzkzODM2ODAwLCJleHAiOjE3OTM4NDA0MDAsIm5hbWUiOiJNYXJpYSBTb3V6YSJ9.YXNzaW5hdHVyYS1maWN0aWNpYS1uYW8tdmVyaWZpY2FkYQ

O decodificador do Me Ajuda Flow mostra o cabeçalho:

{
  "alg": "HS256",
  "typ": "JWT"
}

E o payload:

{
  "iss": "https://auth.exemplo.com.br",
  "sub": "user-1042",
  "aud": "api-pedidos",
  "iat": 1793836800,
  "nbf": 1793836800,
  "exp": 1793840400,
  "name": "Maria Souza"
}

Os campos de tempo são convertidos para datas legíveis: iat e nbf em 2026-11-05 00:00:00 UTC e exp em 2026-11-05 01:00:00 UTC. A diferença entre exp e iat é 1793840400 menos 1793836800, ou seja, 3600 segundos: o token dura uma hora.

Claims comuns

As definições estão na seção 4.1 da RFC 7519. Todas são opcionais pela especificação, mas é comum que o sistema que valida exija algumas.

Os três campos de tempo são datas numéricas: segundos desde 1970-01-01 00:00:00 UTC, e não milissegundos. Um erro comum é tratar 1793840400 como milissegundos e concluir que a data é de janeiro de 1970.

Decodificar não é validar

Esta é a ideia central. Decodificar é desfazer o Base64URL e ler o JSON, e qualquer pessoa faz isso sem chave nenhuma. Validar é conferir a assinatura com a chave certa, o algoritmo esperado e as claims (emissor, destinatário, prazos). A seção 7.2 da RFC 7519 lista esses passos e diz que, se qualquer um falhar, o JWT deve ser rejeitado.

Na prática, isso significa que um token legível pode ser falso. Quem montasse o JSON à mão e colocasse "sub": "user-1042" teria um token tão legível quanto o verdadeiro. O que o distingue é a assinatura, e o decodificador do site não a verifica: ele avisa isso, e informa também se o exp já passou pelo relógio do seu computador. Use a ferramenta de JWT para inspecionar, nunca para decidir se alguém pode entrar.

Riscos mais comuns

Algoritmo none

A RFC 7519 (seção 6) descreve o JWT sem proteção: o cabeçalho traz "alg": "none" e a assinatura é vazia. Teste real com o decodificador do site, com um token assim:

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiJ1c2VyLTEwNDIiLCJhZG1pbiI6dHJ1ZX0.

Ele foi lido sem erro, mostrando "admin": true e a assinatura vazia. Se um servidor aceitasse esse token, qualquer um se declararia administrador. O OWASP orienta garantir que o parser não aceite "alg":"none", e a RFC 8725 (seção 3.2) diz que bibliotecas não devem gerar nem aceitar tokens assim, a menos que o chamador peça explicitamente. A RFC 8725 (seção 3.1) pede ainda que o chamador defina a lista de algoritmos aceitos, em vez de confiar no que o próprio token declara.

Segredo fraco

Em algoritmos como HS256, a assinatura usa um segredo compartilhado. Um segredo curto ou previsível pode ser descoberto por tentativa e erro. A RFC 8725 (seção 3.5) diz que senhas memorizáveis por humanos não devem ser usadas diretamente como chave. O OWASP pede que o segredo seja gerado por um gerador criptograficamente seguro e tenha tamanho pelo menos igual ao da saída do algoritmo: 256 bits para HS256. Para gerar um segredo aleatório, a ferramenta de hash não é o caminho: hash não cria entropia. O correto é usar um gerador criptográfico do seu ambiente.

Token em log e em outros lugares

Quem lê o token lê as claims, e um token válido ainda dentro do prazo funciona como credencial. O OWASP observa que as claims ficam expostas em logs de aplicação, no armazenamento do navegador e em cabeçalhos de referência. Como regra de bom senso (não é uma exigência dessas fontes), evite registrar o token inteiro em logs, e-mails, tickets e prints. Se for preciso diagnosticar, registre apenas o sub e o exp, ou os primeiros caracteres. Se um token válido vazou, trate como credencial exposta e siga o procedimento de revogação do sistema que o emitiu.

Audience e emissor ignorados

Uma assinatura válida não basta. Se o seu serviço aceita um token emitido para outra API, ele está aceitando algo que não era para ele. A RFC 8725 (seção 3.9) pede que a claim aud seja validada por quem recebe.

O que nunca colocar no payload

O OWASP resume: um JWT assinado oferece integridade e autenticidade, mas não confidencialidade. O payload é apenas codificado, não criptografado. A RFC 7519 (seção 12) exige que, havendo informação sensível, sejam tomadas medidas para evitar sua divulgação a terceiros. O OWASP considera omitir dados sensíveis a forma mais simples de reduzir o problema e sugere manter esses dados no servidor, atrás de uma referência opaca.

Prefira identificadores ("sub": "user-1042") a dados ("cpf": "..."). Se for realmente necessário esconder o conteúdo, existe o JWE, token criptografado, que está fora do escopo deste guia.

Checklist rápido ao receber um JWT

  1. Decodifique só para entender o conteúdo e conferir os prazos.
  2. Valide a assinatura em código, com biblioteca madura, com o algoritmo definido por você e a chave do emissor.
  3. Confira iss, aud, exp e nbf.
  4. Não guarde nem registre o token além do necessário.

Para inspecionar um token agora, abra a ferramenta de JWT. Ela decodifica no navegador e avisa que a assinatura não foi verificada.

Ferramentas para usar com este guia

Fontes oficiais