Skip to content
Back to Blog
developerjwt-decodersecurityauthentication

Como Decodificar um JWT (Decodificar vs Verificar)

Qualquer um pode decodificar um JWT em base64 e lê-lo; isso não é o mesmo que verificá-lo. Aqui está a diferença, os ataques que exploram essa lacuna e como decodificar com segurança.

SZ
Founder, Molixa
10 min read
Compartilhar
Como Decodificar um JWT (Decodificar vs Verificar)
Table of contents7 sections

Para decodificar um JWT, faça o base64url-decode das duas primeiras partes separadas por ponto para ler o cabeçalho e o payload como JSON. Decodificar é apenas ler: ele ignora a assinatura, então informa o que as declarações dizem, não se são genuínas. Verificar é a etapa separada que prova que o token não foi adulterado.

Essa distinção é o jogo todo. Um JWT é assinado, não criptografado, o que significa que qualquer pessoa com o token pode ler todas as declarações contidas nele sem uma chave. Tratar "Eu decodifiquei e as declarações parecem corretas" como prova de autenticidade é como vulnerabilidades reais escapam para produção. Vamos desmontar um token, ver exatamente onde a decodificação termina e a verificação começa, e então cobrir os ataques que vivem nessa lacuna.

O que um JWT Realmente Contém#

Um JSON Web Token é composto por três seções codificadas em base64url, unidas por pontos:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0IiwibmFtZSI6IkFkYSIsInJvbGUiOiJhZG1pbiIsImV4cCI6MTczNTY4OTYwMH0.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

As três partes são header.payload.signature. Decodificando as duas primeiras, você obtém JSON legível:

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

// Payload (as declarações)
{ "sub": "1234", "name": "Ada", "role": "admin", "exp": 1735689600 }

O alg informa qual algoritmo assinou o token (aqui HMAC-SHA256). O payload carrega as declarações: sub (subject/ID do usuário), role e exp (expiração como timestamp Unix). A terceira parte, a assinatura, é um hash com chave das duas primeiras. Crucialmente, o payload é apenas base64url, que é codificação, não criptografia. Nunca coloque um segredo no payload de um JWT. Qualquer um pode lê-lo.

Base64url é uma variante segura para URL do base64: troca + e / por - e _ e remove o padding. Se você já tentou decodificar um JWT com uma ferramenta base64 padrão e obteve um erro, geralmente é por causa do conjunto de caracteres.

Decodificar vs Verificar: A Distinção Que Importa#

Essas duas operações parecem semelhantes e são constantemente confundidas em tutoriais. Elas não são a mesma coisa, e misturá-las é um bug de segurança.

DecodificarVerificar
O que fazLê o cabeçalho e o payloadConfirma que a assinatura é válida
Precisa de uma chave?NãoSim (chave secreta ou pública)
Um estranho pode fazer?Sim, com qualquer ferramenta base64Não, apenas o correspondente do signatário
Comprova autenticidade?NãoSim
Quando usarDepuração, inspeção de claimsToda vez que você confiar no token

Aqui está a diferença no código. Decodificar é trivial e não requer confiança:

// APENAS DECODIFICAR: lê claims, não prova nada
function decodeJwt(token) {
  const [header, payload] = token.split(".");
  const json = (part) =>
    JSON.parse(atob(part.replace(/-/g, "+").replace(/_/g, "/")));
  return { header: json(header), payload: json(payload) };
}

const { payload } = decodeJwt(token);
console.log(payload.role); // "admin" ... mas esse token é real?

Esse código retorna felizmente role: "admin" para qualquer token que você passar, incluindo um que um atacante forjou cinco segundos atrás. Verificar é o que torna os claims confiáveis:

// VERIFICAR: checa a assinatura e a expiração antes de confiar em qualquer coisa
import jwt from "jsonwebtoken";

try {
  const claims = jwt.verify(token, process.env.JWT_SECRET, {
    algorithms: ["HS256"], // fixe o algoritmo explicitamente
  });
  // Só agora é seguro agir com base em claims.role
  grantAccess(claims.role);
} catch (err) {
  // Assinatura inválida, token expirado ou algoritmo não permitido
  denyAccess();
}

A regra é simples: decodifique para olhar, verifique para confiar. Qualquer caminho de código que tome uma decisão de autorização deve verificar. Decodificar sem verificar no servidor é equivalente a deixar os usuários editarem suas próprias permissões.

Os Ataques Que Vivem na Lacuna#

Quando desenvolvedores pulam ou tratam incorretamente a verificação, três ataques clássicos surgem. Todos eles exploram o fato de que o token está sob controle do atacante até que a assinatura seja verificada corretamente.

O ataque do algoritmo "none"#

A especificação JWT inclui um valor alg de none, que significa "sem assinatura." Se um servidor lê o algoritmo do próprio cabeçalho do token e confia nele, um atacante pode remover a assinatura, definir "alg": "none" e forjar qualquer payload que desejar:

// Cabeçalho forjado pelo atacante
{ "alg": "none", "typ": "JWT" }

// Payload forjado pelo atacante: admin instantâneo
{ "sub": "9999", "role": "admin" }

Com a assinatura removida e alg definido como none, um verificador ingênuo que "honra" o cabeçalho o aceita. A correção é nunca deixar o token ditar seu próprio algoritmo. Fixe o algoritmo esperado no lado do servidor, exatamente como a opção algorithms: ["HS256"] acima, para que none e qualquer outro valor inesperado sejam rejeitados de imediato.

O ataque de confusão de algoritmo (RS256 para HS256)#

Este é mais sutil e já afetou bibliotecas importantes. Suponha que seu sistema assine tokens com RS256 (assimétrico: uma chave privada assina, uma chave pública verifica). A chave pública é, por definição, pública.

Um atacante pega essa chave pública, altera o cabeçalho para "alg": "HS256" (HMAC simétrico) e assina um token forjado usando a chave pública como o segredo HMAC. Um verificador vulnerável que seleciona o algoritmo do cabeçalho agora executará a verificação HMAC usando a chave pública que já possui, e a assinatura forjada é validada. O atacante acabou de usar sua chave de verificação publicada para assinar tokens.

A defesa é o mesmo princípio: fixe o algoritmo. Se seu servidor espera RS256, configure-o para aceitar apenas RS256 e verificar com a chave pública como uma chave RSA, nunca como um segredo HMAC. Permitir que o cabeçalho escolha é a causa raiz em todos os casos.

Ignorar expiração e outras declarações#

Mesmo uma assinatura perfeitamente verificada não significa que o token é válido no momento. A verificação confirma que o token foi emitido por você e não foi alterado; ela não verifica, por si só, se o token ainda está dentro do prazo ou se é destinado a este público. Sempre valide:

  • exp (expiração) e nbf (não antes) para que tokens expirados ou futuros sejam rejeitados.
  • aud (público-alvo) para que um token criado para um serviço não possa ser reproduzido contra outro.
  • iss (emissor) para que você aceite apenas tokens do provedor de identidade em que confia.

A maioria das bibliotecas verifica exp automaticamente ao chamar verify, mas aud e iss geralmente exigem que você passe os valores esperados explicitamente.

Onde você armazena e envia o token também importa#

A verificação protege o conteúdo do token, mas o manuseio do token é uma superfície de ataque própria. Alguns pontos inegociáveis:

  • Prefira cookies HTTP-only em vez de localStorage para tokens de sessão, para que scripts do lado do cliente (e qualquer payload XSS) não possam lê-los.
  • Sempre use HTTPS para que o token não seja interceptado durante a transmissão.
  • Mantenha os payloads mínimos e não sensíveis. Como qualquer pessoa pode decodificar o payload, nunca armazene senhas, PII completa ou segredos nele.
  • Use tempos de vida curtos com tokens de atualização para que um token de acesso vazado expire rapidamente.

Um token vazado é um token válido até expirar. É por isso que as janelas de expiração e a higiene do armazenamento são tão importantes quanto a matemática de assinatura.

Como Decodificar um JWT com Segurança para Depuração#

Você precisará inspecionar tokens constantemente ao construir autenticação: verificando quais claims um provedor de identidade emitiu, depurando um erro 401, confirmando uma expiração. O problema é que um JWT é uma credencial ativa. Colar um token de sessão real em um site aleatório significa que o servidor desse site agora tem um token funcional para sua conta.

Passo 1: Use um decodificador que rode no seu navegador#

Recorra a um decodificador JWT gratuito que faz toda a análise no lado do cliente. Quando a decodificação acontece inteiramente na aba do navegador, o token nunca é transmitido para lugar nenhum, então mesmo um token de produção permanece na sua máquina. Este é o hábito mais importante ao lidar com tokens reais: confirme que a ferramenta é do lado do cliente antes de colar.

Passo 2: Leia o cabeçalho, o payload e a expiração#

O decodificador divide o token e mostra o cabeçalho e o payload como JSON formatado, além de uma expiração legível para que você não precise converter um timestamp Unix manualmente. Verifique o alg, examine os claims e confirme que exp está no futuro. Lembre-se de que você está lendo, não validando, nesta etapa.

Passo 3: Verifique a assinatura apenas com um segredo que não seja de produção#

Se o decodificador e verificador JWT permitir testar uma assinatura, cole apenas um segredo de teste ou desenvolvimento, nunca uma chave de assinatura de produção, em qualquer formulário web. A matemática da assinatura também é algo que você pode reproduzir localmente: uma assinatura HS256 é apenas um HMAC, que você pode calcular com um gerador de hash, e as partes base64url são decodificadas com um codificador e decodificador Base64. Para uma visão mais ampla sobre como lidar com tokens com segurança, veja nosso guia sobre decodificadores JWT e segurança de tokens.

A Conclusão#

Decodificar um JWT lê as claims; verificar prova que elas são autênticas. São operações diferentes com requisitos diferentes, e confundi-las é a raiz dos ataques de algoritmo none e de confusão de algoritmo. No servidor, verifique cada token, fixe o algoritmo explicitamente e cheque exp, aud e iss. Para depuração, decodifique localmente para que uma credencial ativa nunca saia do seu navegador.

Perguntas Frequentes#

Como decodificar um JWT? Divida o token nos dois pontos em três partes, depois decodifique a primeira parte (cabeçalho) e a segunda parte (payload) em JSON usando base64url. A terceira parte é a assinatura e não deve ser lida. A decodificação não requer chave e apenas mostra as claims, não confirma se o token é autêntico.

Qual é a diferença entre decodificar e verificar um JWT? Decodificar lê o cabeçalho e o payload sem precisar de chave, então qualquer um pode fazer. Verificar recalcula a assinatura com a chave secreta ou pública para confirmar que o token foi emitido por você e não foi alterado. Decodificar informa o que as claims dizem; apenas verificar diz se você deve confiar nelas.

É seguro decodificar um JWT online? Apenas com uma ferramenta que decodifica inteiramente no seu navegador. Um JWT é uma credencial ativa, então colar um token de sessão real em um site que o envia para um servidor entrega a esse servidor um token funcional para sua conta. Use um decodificador do lado do cliente para que o token nunca saia da sua aba.

O que é o ataque de algoritmo "none" em JWT? Explora servidores que leem o algoritmo de assinatura do próprio cabeçalho do token. Um atacante define "alg": "none", remove a assinatura e forja qualquer payload. Um verificador que honra o cabeçalho aceita o token não assinado. A correção é fixar o algoritmo esperado no servidor e rejeitar none completamente.

Alguém pode ler os dados dentro do meu JWT? Sim. Um JWT é assinado, não criptografado, então o payload é apenas codificado em base64url e qualquer pessoa com o token pode decodificar e ler todas as claims. Nunca armazene senhas, segredos ou dados pessoais sensíveis no payload de um JWT. A assinatura protege contra adulteração, não contra leitura.

Como verificar se um JWT expirou? Decodifique o payload e leia a claim exp, um timestamp Unix em segundos; se estiver no passado, o token expirou. Durante a verificação real, a maioria das bibliotecas rejeita tokens expirados automaticamente ao chamar verify. Um decodificador que mostra a expiração em formato legível permite confirmar isso rapidamente durante a depuração.

developerjwt-decodersecurityauthentication

More from Molixa

Try Molixa Tools

50+ free AI tools for content creation, SEO, coding, and more. No signup, no watermark.

Explore all tools
Decodificar vs Verificar um JWT com Segurança | Molixa | Molixa