Um debugger de JWT privacy-safe que nunca manda seu token (2026)
Um debugger de JWT privacy-safe que nunca manda seu token
Você está debugando um fluxo OAuth às 23 h, pega um JWT da sua aba Network para confirmar que uma claim está setada corretamente, cola no primeiro decoder de JWT que o Google mostra e um momento depois lembra que acabou de dar a um site terceiro um token de acesso funcional assinado pelo seu provedor de identidade de produção — totalmente capaz de logar na conta do seu cliente, chamar sua API interna e ler o que quer que os escopos do token permitam.
Quase todo decoder JWT popular na web pública — jwt.io, jwtdecoder.net, as dezenas de clones — posta seu token colado para um servidor antes de mostrar o que tem dentro. As páginas de privacidade deles dizem “não armazenamos” o que pode até ser verdade, mas o token ainda cruzou a internet aberta, bateu num endpoint HTTPS de terceiro e viveu no log de acesso HTTP deles por algum período de retenção. Para tokens de produção, isso é um incidente de segurança que vale revelação.
Este guia explica como JWTs realmente funcionam, o que “decodar” um JWT realmente faz e como debugar com segurança usando o JWT Decoder do Ai2Done que roda 100 % na sua aba.
TL;DR
- Um JWT é só três strings base64 separadas por pontos — header, payload e signature.
- “Decodar” um JWT é só base64-decodar as duas primeiras partes. Não é verificação de assinatura.
- A maioria dos decoders JWT online posta seu token para o servidor deles. Mesmo se dizem que não logam, o token ainda deixou sua máquina e entrou num log de acesso em algum lugar.
- O JWT Decoder do Ai2Done roda inteiramente no seu navegador — seu token nunca deixa sua aba.
- Para tokens de produção com privilégios reais, esse é o único padrão seguro. Trate cada colagem de um JWT de produção numa ferramenta de terceiros como se tivesse entregado a senha para alguém.
Por que isso é mais difícil do que parece
Um JWT (JSON Web Token, RFC 7519) é estruturalmente trivial:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJleHAiOjE3NTAwMDAwMDB9.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
Isso são três partes separadas por .:
- Header (
eyJhbGciOiJIUzI1NiJ9) — JSON base64-encoded{"alg":"HS256"}descrevendo o algoritmo de assinatura. - Payload (
eyJzdWIi...) — JSON base64-encoded com as claims reais (sub,exp, campos customizados). - Signature (
dBjftJeZ...) — HMAC ou RSA/ECDSA sobreheader.payload, usada para verificar integridade.
“Decodar” um JWT significa base64-decodar as partes 1 e 2 para ler o JSON dentro. Isso exige nenhuma chave secreta, nenhuma chamada de rede, nenhum servidor. É uma função JavaScript de 5 linhas. Mesmo assim 99 % dos decoders JWT online insistem em fazer round-trip do seu token pelo backend deles, o que significa que o token entra:
- No log de terminação HTTPS do servidor deles
- No log de acesso do reverse proxy
- Possivelmente no log de aplicação (dependendo de como implementam)
- Nos logs edge da CDN deles (Cloudflare, Fastly etc.)
- Nos logs correspondentes de quaisquer redes de anúncios parceiras, serviços de tracking de erro ou provedores de analytics carregados na página
Mesmo com as melhores intenções do lado do operador, seu token de produção agora está persistido em 4-6 arquivos de log diferentes, em 2-3 empresas diferentes, com períodos de retenção variando de 7 dias a “para sempre”. Um atacante determinado comprometendo qualquer um desses alvos tem um bearer token funcional para os recursos do seu cliente.
Isso não é paranoia. É modelagem de ameaça padrão para qualquer um lidando com credenciais de produção.
Método 1: Ai2Done JWT Decoder (no navegador, o jeito certo)
O JWT Decoder do Ai2Done são 200 linhas de JavaScript vanilla rodando na sua aba. Cole um token, veja o que tem dentro, feche a aba, e o token sumiu para sempre. O fluxo:
- Abra /tools/jwt_decoder em qualquer navegador.
- Cole seu JWT na área de input.
- O header e payload decodificados aparecem instantaneamente em painéis JSON com syntax highlight.
- Opcionalmente, cole seu secret de assinatura (HS256) ou chave pública (RS256) para verificar a assinatura localmente. A verificação também roda inteiramente no cliente.
O que você ganha out of the box:
- Decodificação de header com algoritmo e key ID
- Decodificação de payload com todas as claims customizadas e claims padrão (
iss,sub,aud,exp,nbf,iat,jti) - Timestamps legíveis por humanos —
exp: 1750000000também é mostrado como “em 47 minutos” para você ver imediatamente se o token está expirado ou perto de expirar - Warnings de validação de claim — se
expestá no passado, o campo é destacado em vermelho; seaudnão casa com um valor que você espera, você pode colar oaudesperado para comparação instantânea - Verificação de assinatura — cole seu secret HS256, chave pública RS256 (PEM) ou URI JWKS, e a ferramenta te diz se a assinatura é válida. A verificação usa Web Crypto API inteiramente no navegador.
O bundle inteiro é ~40 KB. Carrega em <1 segundo em qualquer dispositivo, funciona offline uma vez cacheado e tem zero chamadas de rede depois do carregamento inicial da página.
Método 2: um script de 5 linhas no seu terminal
Para developers que já trabalham no terminal, o decoder JWT mais simples possível é uma linha de bash:
echo "SEU_JWT_AQUI" | cut -d. -f2 | base64 -d 2>/dev/null | jq .
Isso:
- Pipa o JWT para
cutpara pegar a segunda parte (payload) - base64-decoda (
2>/dev/nullsilencia warnings de padding) - Pretty-prints com
jq
Para o header, troque f2 por f1. Para verificação de assinatura, use uma lib real — python -c "import jwt; print(jwt.decode(...))" ou o equivalente na sua linguagem. Não tente implementar verificação HMAC-SHA256 em bash.
Esta é a resposta certa para “já estou SSHed num servidor e preciso inspecionar um token agora”. É overkill se você já está num navegador.
Método 3: um app nativo macOS / Windows
Para quem odeia ferramentas de navegador, há vários decoders JWT só offline:
- macOS: JWT Inspector (grátis, da App Store)
- Windows: JWT Decoder pela IDESoft (grátis, da MS Store)
- Multi-plataforma: extensão VS Code “JWT Debugger” (funciona dentro do seu editor)
Todos rodam inteiramente no seu dispositivo sem requisições de rede. Escolha o que se encaixa no seu fluxo.
Como construímos (deep-dive técnico)
O JWT Decoder do Ai2Done é deliberadamente minimalista:
- Sem frameworks — JS vanilla, ~200 linhas, ~40 KB gzipped. Carrega instantaneamente até numa conexão 3G.
- Sem analytics, sem telemetria — não sabemos nem quantas pessoas usam, por design. Pageviews são registrados no nível de rota (
/tools/jwt_decoderrecebeu X visitas) mas nunca com qualquer informação derivada do token. - base64url-safe por padrão — JWTs usam a variante URL-safe do base64 (
-_em vez de+/); lidamos com ambas. - Web Crypto para verificação de assinatura —
crypto.subtle.verify()nativamente suporta HMAC-SHA256/384/512 e RS256/384/512. ES256/384 (ECDSA) também funciona em navegadores modernos. PS256 (RSA-PSS) requer um pequeno shim JS porque alguns navegadores antigos não têm. - Suporte a JWKS — cole uma URI JWKS (ex.:
https://accounts.google.com/.well-known/jwks.json), a ferramenta busca o JWK set, encontra a chave que casa com okiddo token e verifica a assinatura. O fetch acontece do seu navegador direto para o IdP, nunca pelo nosso servidor.
A única decisão de design que vale sinalizar: deliberadamente não oferecemos funcionalidade de “assinar um JWT”. A ferramenta é read-only. Assinar exige uma chave secreta, e não queremos usuários no hábito de colar seu secret HMAC ou chave privada RSA em web apps. Assine seus tokens com uma lib real no seu código de aplicação; use esta ferramenta para verificar o que saiu.
FAQ
Q: “Decodar” um JWT é um risco de segurança por si só? A: Não — base64-decodar o header e payload revela só o que o issuer escolheu colocar lá. A spec JWT é explícita: o payload é base64-encoded, não criptografado. Qualquer um que tem o token consegue ler o que tem dentro. O risco real é deixar o próprio token vazar, porque o token é uma credencial bearer — quem tem ele pode usar.
Q: O exp do meu token está no passado mas a API ainda aceita. Por quê?
A: Algumas razões possíveis: (1) o servidor está checando uma claim de timestamp diferente como nbf ou iat e ignorando exp, (2) o servidor tem clock skew e aceita tokens até N minutos após expiração, (3) o tipo de token é na verdade um refresh token que não expira tão rápido quanto access tokens ou (4) a API genuinamente tem um bug. Cheque a política de validação do seu IdP.
Q: Como verifico a assinatura sem a chave pública do IdP? A: Não consegue, por design — esse é o ponto inteiro. A assinatura prova que o token foi emitido por alguém que sabia o secret de assinatura. Se você não tem a chave pública (para RS256) ou o secret compartilhado (para HS256), não consegue verificar integridade. O decoder vai te dizer “não verificado — provê uma chave para verificar”. Esse é o comportamento correto.
Q: Por que a ferramenta mostra algumas claims como padrão e outras como customizadas?
A: RFC 7519 reserva um conjunto de nomes de claim padrão: iss, sub, aud, exp, nbf, iat, jti. Qualquer outra é customizada (ex.: name, email, roles, claims específicas da aplicação). O decoder destaca claims padrão com sua semântica definida pela RFC e trata todo o resto como JSON de forma livre.
Q: Posso decodar um token JWE criptografado?
A: Não sem a chave de descriptografia. JWE (JSON Web Encryption, RFC 7516) é genuinamente criptografado, então o payload é opaco sem a chave. A ferramenta detecta JWE vs. JWS baseado na claim enc do header e te diz que não consegue decodar tokens criptografados sem chave (e não oferecemos colagem de chave porque é uma operação sensível que deveria acontecer no seu próprio código, não numa ferramenta web).
Q: A ferramenta funciona offline? A: Sim. Depois da primeira visita, a ferramenta está no cache HTTP do seu navegador e funciona sem acesso à internet — útil ao debugar tokens em ambientes airgapped ou quando sua rede está fora.
Experimente agora
Debugue seu JWT sem entregar para um estranho:
Cole, veja, feche. Seu token nunca deixa sua aba.
Leituras relacionadas
- JSON, YAML, XML, CSV — round-tripping com um único toolbox — para inspecionar o JSON dentro de um JWT em mais detalhe
- Parser de expressão Cron explicado para não-DevOps — outra ferramenta dev que roda inteiramente no seu navegador
- Processamento WASM no cliente: por que rodamos tudo no seu navegador
- Navegue por todas as ferramentas de developer
Última atualização 2026-06-14. O JWT Decoder roda 100 % na sua aba — seus tokens nunca deixam seu dispositivo. Não temos log de servidor, sem analytics em conteúdo de token e sem jeito de recuperar um token decodificado depois que você fecha a aba.