JWT (JSON Web Token / jwt decoder / jwt online / decode jwt) nao e criptografia, e codificacao — o payload usa base64url que decodifica para texto plano em um segundo, entao nunca coloque senhas / PII / cartoes bancarios / numeros de telefone no payload JWT. Este artigo cobre 8 foot-guns reais de seguranca JWT + 5 cenarios de ataque de falsificacao + plano de protecao 7 dias, que juntos evitam pelo menos 90% das vulnerabilidades.

Resumo em 30 Segundos

  • JWT nao e criptografia, e codificacao — muitos desenvolvedores pensam que JWT e “seguro” porque a codificacao base64url parece ilegivel, mas qualquer pessoa pode decodificar em um segundo para obter o payload em texto plano. JWT payload = texto plano, apenas assinado, nao criptografado
  • JWT padrao 4 riscos principais: ataque alg=none / confusao de chave publica HS256 vs RS256 / exp nao validado permite que tokens expirados passem / remocao de assinatura algumas bibliotecas aceitam como fallback
  • Implantacao JWT 4 foot-guns: JWT secret hardcoded em Git scaneado em horas / injecao de kid qualquer arquivo usado como chave / sem blacklist tokens antigos validos apos logout / expiracao longa (7 dias) mudanca de senha nao invalida tokens
  • 5 cenarios reais de ataque: vazamento de telefone em texto plano / falsificacao alg=none / assinatura HS256 com chave publica / exp nao validado / remocao de assinatura passa validacao
  • Plano de protecao 7 dias (cada um ≤ 30 minutos): forcar whitelist de algoritmo (sempre verificar exp) / JWT secret via env vars + .gitignore / validacao estrita de formato kid (whitelist de caracteres) / assinatura deve verificar (none rejeitado) / expiracao curta (15 minutos) + rotacao de refresh token / blacklist + estado revoke em BD / nunca colocar PII em payload JWT
  • Use o Decodificador JWT Piick localmente para decodificar tokens suspeitos e verificar header / payload / exp / assinatura — 100% local sem upload, nao polui seu log de auditoria durante o debug

8 Foot-Guns Reais de JWT

Foot-Gun 1: JWT Nao E Criptografia, E Codificacao

Sintoma: Voce coloca o numero de telefone / email / ultimos 4 digitos do cartao / hash de identificacao do usuario no payload JWT, pensando “o token parece texto ilegivel, outros nao conseguem ler”. Ate que um dia o payload vaza, base64url decodifica — telefone + email + hash de ID em texto plano tudo exposto, multa de conformidade GDPR a partir de ¥500k.

Por que: JWT tem tres segmentos header.payload.signature, apenas a assinatura esta assinada (HMAC/RSA assinada para evitar manipulacao), mas o payload em si e texto plano codificado com base64url. Qualquer pessoa com o token (incluindo logs de frontend / CDN / proxy reverso / DevTools do navegador) pode atob(token.split('.')[1]) decodificar para JSON em um segundo. JWT nao e criptografia, e “texto plano a prova de manipulacao”.

Correcao:

  • Nunca coloque PII (Informacao de Identificacao Pessoal) no payload JWT — sem telefone / email / cartao de identificacao / cartao bancario / endereco / hash de senha
  • O payload JWT so contem “identificadores nao sensiveis” — user_id (UUID de banco de dados, nao numero derivavel), role (papel, nao estrutura organizacional), exp / iat / nbf (timestamps)
  • Campos verdadeiramente sensiveis: coloque no banco de dados do backend, o JWT so tem user_id, consulte o BD quando necessario
  • Se voce realmente precisa de dados sensiveis no token: use JWE (JSON Web Encryption) — mas 99% dos cenarios nao precisam

Cenario real: Uma empresa SaaS colocou numeros de telefone de usuarios diretamente no payload JWT (para “economizar uma consulta ao banco de dados”), 3 meses depois o JWT secret vazou, 2 milhoes de telefones de usuarios obtidos atraves de decodificacao do payload em um clique, multas duplas GDPR + Lei de Protecao de Informacao Pessoal da China ¥8 milhoes.

Foot-Gun 2: Ataque alg=none

Sintoma: Sua biblioteca JWT e antiga (jwt-go versao antiga / jsonwebtoken antes de 4.x / python-jose versao velha), um atacante constroi header = {"alg": "none"} + payload arbitrario, forja um token admin, sua biblioteca do servidor aceita, o atacante obtem diretamente privilegios de admin.

Por que: O padrao JWT antigo RFC 7519 nao exigia a validacao do lado do servidor do campo alg, algumas bibliotecas ao ver alg: "none" confiam diretamente no payload sem verificar a assinatura (porque “none” = “sem assinatura”, a biblioteca pula o passo de verificacao). Este e o ataque mais classico na historia do JWT, em 2015 Auth0 e outras bibliotecas multiplas foram afetadas.

Correcao:

  • Forcar whitelist de algoritmo (sempre especifique algoritmos permitidos): jsonwebtoken.verify com whitelist de algoritmos: [‘HS256’]
  • Sempre rejeitar alg: "none" (mesmo se compativel com RFC)
  • Atualizar para a ultima versao da biblioteca JWT (corrige vulnerabilidades conhecidas de alg=none)
  • Revisao de codigo verificando chamadas verify — sem parametro de algoritmos especificado e uma vulnerabilidade

Cenario real: Relatorio publico da Auth0 2015: biblioteca Node.js jsonwebtoken versoes antes de 4.2.2 aceitam alg: "none" por padrao, qualquer servidor que aceite tokens sem atualizar estava sob ataque. Apos o conserto todas as bibliotecas modernas exigem especificar algoritmos.

Foot-Gun 3: Ataque de Confusao de Chave Publica HS256 vs RS256

Sintoma: Voce usa RS256 (RSA assimetrico), chave publica colocada no frontend / gateway para verificar tokens, mas algum desenvolvedor escreveu a funcao verify, ao ver header alg: "HS256" usa a mesma chave publica como secret HMAC para verificar. O atacante obtem a chave publica (ja e publica) → usa a chave publica como secret HMAC para assinar token HS256 → o servidor usa a mesma chave publica para “verificar”, passa → token admin falso burla autenticacao.

Por que: RS256 usa chave privada RSA para assinar, chave publica para verificar; HS256 usa o mesmo secret tanto para assinar quanto para verificar. Se o codigo do servidor confunde “tenho uma chave, use-a”, o atacante pode usar qualquer tipo de chave para forjar tokens. Esta e a vulnerabilidade mais classica na implantacao de RS256.

Correcao:

  • Sempre forcar que o alg no header corresponda ao algoritmo configurado — algoritmo escrito na config (servico RS256 sempre verifica alg=RS256 esperado)
  • secret / chave publica com nomes estritamente separados (evitar confusao): const JWT_PRIVATE_KEY = …; // so para assinar const JWT_PUBLIC_KEY = …; // so para verificar
  • Revisao de codigo verificando funcao verify — forcar lista de algoritmos verify (whitelist), nao aceitar alg auto-reportado do token
  • Use bibliotecas JWT maduras (PyJWT / jsonwebtoken / java-jwt) em vez de implementar verify voce mesmo

Cenario real: 2018 o servico de gateway JWT de um banco usou RS256, mas a funcao verify tinha um bug de implementacao: jwt.verify(token, publicKey) nao especificava algoritmos, o atacante usou a chave publica como secret HMAC para assinar token HS256 passando a verificacao, forjou transferencia de $10 milhoes.

Foot-Gun 4: Campo exp Nao Validado ou Validacao Vazada

Sintoma: Seu JWT tem campo exp (tempo de expiracao), assumindo validacao automatica, mas alguma rota de codigo marginal no servidor so verifica a assinatura nao exp (por exemplo, uma rota de fallback), os tokens expirados continuam sendo aceitos, a sessao nunca expira. O usuario muda senha / e desabilitado / faz logout, o token continua sendo utilizavel ate que exp expire.

Por que: O padrao JWT RFC 7519 § 4.1.4 especifica que exp e MUST validate, mas muitas bibliotecas nao forcam a validacao de exp por padrao (por compatibilidade com certos cenarios como “tokens permanentes”). Se a chamada verify nao passa explicitamente ignoreExpiration: false ou verifica manualmente no codigo em vez de usar a biblioteca, exp e omitido.

Correcao:

  • Sempre verificar exp explicitamente (nao depender de valores padrao): jwt.verify com algorithms: [‘HS256’] e ignoreExpiration: false
  • Tempo de expiracao curto (access token 15 minutos, refresh token 7-30 dias)
  • relogio do servidor sincronizado com NTP (evitar desvio do relogio que cause expiracao prematura / tardia do token)
  • O cliente nao deve confiar no tempo local — use Date.now() / time.time() e o tempo do servidor para calcular a diferenca de exp

Cenario real: A expiracao do access token de um servico SaaS era de 7 dias, um usuario mudou a senha mas o atacante usou o token antigo, pode acessar todos os recursos do usuario durante 7 dias. Encurtar para 15 minutos + rotacao de refresh token e o padrao da industria.

Foot-Gun 5: Vazamento de JWT Secret / Chave Privada Hardcoded em Git

Sintoma: Voce escreve `const JWT_SECRET=*** em codigo + commit + push para GitHub (mesmo repositorio privado, saida de funcionario / roubo de conta / vazamento interno). O secret scanning do GitHub escaneia em 30 segundos, o JWT secret vaza igual as API keys, o atacante usa este secret para assinar tokens para qualquer usuario qualquer payload, todo o sistema comprometido.

Por que: O historico do Git nunca e apagado (git filter-branch so altera o ponteiro do branch, os objetos commit antigos permanecem em .git/objects/ por 30 dias). O JWT secret e o mesmo nivel de desastre que a API key apos o vazamento — o atacante obtem o secret = todo o sistema de autenticacao comprometido = identidade de usuario arbitrariamente falsificada.

Correcao:

  • JWT secret via env vars + .gitignore: const JWT_SECRET=*** Nunca hardcode em codigo
  • CI usa OIDC / tokens de curto prazo, sem secrets de longo prazo
  • JWT secret igual a rotacao + monitoramento de API key — o plano de protecao de 7 dias do batch-24 api-key-leak-prevention aplica completamente

Cenario real: Uma empresa fintech jwt-secret escrita em config/default.json commitada no GitHub, o secret scanning do GitHub 30 segundos email + webhook para o atacante, em 1 hora 2 milhoes de JWTs de usuarios re-assinados, saldos de usuarios arbitrariamente manipulados. Correcao: mover secret para Vault / AWS Secrets Manager + CI OIDC.

Foot-Gun 6: Ataque de Injecao de kid (Key ID)

Sintoma: Voce usa arquitetura RS256 multi-chave, o campo kid no header especifica qual chave publica usar, o servidor getKey(header.kid) consulta a tabela de chaves publicas baseado em kid. O atacante constroi kid: "../../etc/passwd" ou kid: "' OR 1=1--", algumas bibliotecas JWT diretamente fs.readFileSync(getKey(kid)) ou concatenam consulta SQL, causando leitura arbitraria de arquivos / injecao SQL.

Por que: O campo kid foi pensado para ser “qual chave usar para verificar”, mas as bibliotecas ao implementar getKey frequentemente tratam kid como nome de arquivo / parametro SQL / caminho URL, sem validacao de caracteres whitelist. O atacante usa kid para path traversal (LFI / RCE) ou injecao SQL.

Correcao:

  • kid whitelist estrito de caracteres (apenas permitir [A-Za-z0-9_-]): validar kid com regex whitelist (alfanumerico + hifen + underscore, 1-32 caracteres)
  • O valor kid deve estar no conjunto de chaves conhecido (verificacao Map.has(kid))
  • Nao tratar kid como nome de arquivo / parametro SQL / caminho URL
  • Use bibliotecas JWT maduras (implementar getKey voce mesmo e facil que tenha bugs)

Cenario real: Node.js jsonwebtoken + alguns plugins suportam o campo jwk do header, o atacante constroi jwk: [objeto com chave controlada pelo atacante], faz com que o servidor use a chave fornecida pelo atacante para verificar = definitivamente passa. Correcao: rejeitar campos jwk / jku / x5u proprios do token, apenas usar a chave configurada no servidor.

Foot-Gun 7: Ataque de Remocao de Assinatura

Sintoma: Quando voce escreve a funcao verify, se alguma condicao limite (por exemplo, header.alg nao corresponde a whitelist) nao e tratada, algumas bibliotecas caem em aceitar o token sem assinatura (header.payload. seguido de string vazia). O atacante modifica o payload (por exemplo, muda role para admin) → remove a assinatura → alguma rota de fallback pula a verificacao de assinatura → token falso passa a validacao.

Por que: O formato JWT e header.payload.signature, se apenas header.payload. for passado, a biblioteca analisa o segmento de assinatura como vazio, algumas implementacoes de bibliotecas if (!signature) return payload (porque “sem assinatura = nao precisa verificar”), burla toda a verificacao de assinatura.

Correcao:

  • Sempre verificar os 3 segmentos completos (header.payload.signature todos devem ter conteudo)
  • Rejeitar tokens com assinatura vazia (mesmo se compativel com RFC)
  • Sempre usar bibliotecas maduras (nao dividir + verificar voce mesmo)
  • Caso de teste: construir header.payload. enviar, deve ser rejeitado

Cenario real: Bug de implementacao de alguma biblioteca JWT: quando a assinatura esta vazia diretamente retorna payload, o atacante captura um token valido → modifica o payload (role → admin) → remove a assinatura → passa a validacao → obtem privilegios de admin. Correcao: antes de verify verificar token.split(’.‘).length === 3 e o terceiro segmento nao esta vazio.

Foot-Gun 8: A Lista de Revogacao de JWT Nao Existe

Sintoma: O usuario muda senha / e desabilitado pelo admin / faz logout ativamente, o token antigo continua valido ate que exp expire. A expiracao do access token de 7 dias significa que o atacante usando o token antigo pode acessar durante 7 dias apos a mudanca de senha. Sem mecanismo de blacklist / revoke = uma vez que o JWT e emitido nao da para gerenciar.

Por que: JWT e projetado para ser stateless — o servidor nao armazena tokens, apenas verifica a assinatura. Bom para escalonamento horizontal, ruim para revogacao. Se voce quer “revogar imediatamente este token”, deve ter blacklist ou mecanismo de refresh token.

Correcao:

  • Access token de expiracao curta + rotacao de refresh token: access token: expiracao de 15 minutos refresh token: expiracao de 7 dias, apos cada uso regenerar novo (rotacao, o refresh token antigo e invalidado)
  • refresh token armazenado em BD + blacklist (marcar o refresh token como revogado ao fazer logout)
  • Revogar todos os refresh tokens ao mudar a senha (forcar re-login)
  • Redis blacklist (cenarios de acesso de alta frequencia usam Redis para cachear tokens revogados, TTL = validade restante do token)

Cenario real: Um usuario SaaS mudou a senha mas o atacante usou o token roubado acessou durante 7 dias → email do usuario modificado / cartao de credito adicionado → so descoberto apos a reclamacao do servico ao cliente. Correcao: access token 15 minutos + rotacao de refresh token + mudanca de senha revoga todos os refresh tokens.

5 Cenarios Reais de Ataque

Cenario 1: Vazamento de Telefone em Texto Plano

Sintoma: Uma API SaaS retorna JWT do usuario contendo {user_id: 123, phone: "13812345678", email: "user@example.com"}, o frontend usa este token para mostrar o estado “logado”. 3 meses depois o JWT secret vaza, todos os tokens decodificados, 2 milhoes de telefones + emails de usuarios obtidos em um lote.

Correcao:

  • O payload JWT so contem user_id (UUID, nao numero derivavel)
  • Quando o frontend precisa mostrar o telefone, usa user_id para chamar a API do backend para consultar (nao confie na decodificacao do token)
  • Nunca coloque PII no payload JWT

Cenario 2: Token Falsificado com alg=none

Sintoma: Um servico Node.js antigo usa jsonwebtoken@4.2.1, o verify nao especifica algoritmos, o atacante constroi header = {"alg": "none", "typ": "JWT"} + payload {user_id: 1, role: "admin"} + assinatura deixada vazia, diretamente forja token admin passando a validacao.

Correcao:

  • Forcar whitelist de algoritmos: jwt.verify(token, secret, { algorithms: ['HS256'] })
  • Atualizar jsonwebtoken para a ultima versao

Cenario 3: Ataque de Confusao de Chave Publica HS256

Sintoma: O servico JWT de um banco usa RS256 (chave privada assina, chave publica verifica), chave publica no gateway da API, funcao verify jwt.verify(token, publicKey) nao especifica algoritmos. O atacante usa a chave publica como secret HMAC para assinar token HS256, o servidor usa a chave publica para “verificar”, passa → token admin falso transfere $10 milhoes.

Correcao:

  • verify forcar whitelist de algoritmos: jwt.verify(token, publicKey, { algorithms: ['RS256'] })
  • Chave privada / chave publica com nomes estritamente separados (evitar confusao em getKey)

Cenario 4: exp Nao Validado, Token Expirado Continua Sendo Aceito

Sintoma: Um servico JWT tem exp, mas a biblioteca verify por padrao ignoreExpiration: true (por compatibilidade com “tokens permanentes”), todos os tokens expirados passam. O usuario muda a senha mas o atacante usa o token antigo continua sendo utilizavel durante 30 dias.

Correcao:

  • Verificar exp explicitamente: jwt.verify(token, secret, { algorithms: ['HS256'], ignoreExpiration: false })
  • Nunca depender de valores padrao

Cenario 5: Ataque de Remocao de Assinatura

Sintoma: Bug de implementacao da biblioteca verify de algum JWT: quando a assinatura esta vazia diretamente retorna payload. O atacante captura um token valido → modifica o payload → remove a assinatura → header.payload. envia, burla a verificacao de assinatura.

Correcao:

  • Antes de verify verificar token.split(’.‘).length === 3 e o terceiro segmento nao esta vazio
  • Sempre usar biblioteca JWT madura (dividir + verificar voce mesmo e facil que tenha bugs)
  • Caso de teste: token = "header.payload." deve ser rejeitado

Plano de Protecao 7 Dias

Dia 1: Forcar Whitelist de Algoritmo

5 minutos. Revisao de codigo verificando todas as chamadas verify JWT, garantir especificar whitelist de algoritmos:

  • Node.js jsonwebtoken: jwt.verify(token, secret, { algorithms: ['HS256'] })
  • Python PyJWT: jwt.decode(token, secret, algorithms=['HS256'])
  • Java java-jwt: Jwts.parser().verifyWith(key).build().parseSignedClaims(token)
  • Sempre rejeitar alg=none

Efeito: Ataque alg=none + ataque de confusao HS256/RS256 completamente bloqueados.

Dia 2: JWT Secret via Variaveis de Ambiente

30 minutos. Mover todos os JWT secret / chave privada de arquivos de codigo / config para variaveis de ambiente:

  • Criar .env.example (placeholder, sem secret real, commitar)
  • .gitignore adicionar .env
  • Codigo mudar para `const JWT_SECRET=*** CI usa GitHub Actions secrets + OIDC

Efeito: Risco de vazamento de JWT secret no Git reduzido a zero.

Dia 3: Sempre Verificar exp + Expiracao Curta

1 hora. Revisao de codigo de todas as chamadas verify, garantir:

  • ignoreExpiration: false especificado explicitamente
  • expiracao do access token ≤ 15 minutos
  • expiracao do refresh token ≤ 7 dias
  • rotacao do refresh token (regenerar apos cada uso)

Efeito: Apos o vazamento do token maximo 15 minutos acessivel, nao 7 dias.

Dia 4: kid Whitelist Estrito

30 minutos. Revisao de codigo da funcao getKey, garantir:

  • O valor kid deve corresponder a ^[A-Za-z0-9_-]{1,32}$
  • O valor kid deve estar no conjunto de chaves conhecido
  • Nao tratar kid como nome de arquivo / parametro SQL / caminho URL
  • Rejeitar campos jwk / jku / x5u proprios do token (usar chave configurada no servidor)

Efeito: Ataque de injecao kid completamente bloqueado.

Dia 5: A Assinatura Deve Ser Verificada

15 minutos. Revisao de codigo de pre-checagens de verify:

  • token.split(’.‘).length === 3
  • Terceiro segmento (assinatura) nao vazio
  • Versao da biblioteca e a ultima (sem vulnerabilidades conhecidas de remocao de assinatura)
  • Caso de teste: token = "header.payload." deve ser rejeitado

Efeito: Ataque de remocao de assinatura completamente bloqueado.

Dia 6: Mecanismo de Revogacao de refresh token

Meio dia. Implementar rotacao de refresh token + blacklist:

  • Banco de dados armazena refresh tokens (associados user_id + device + estado revoked)
  • Apos cada uso de refresh token: gerar novo, marcar antigo como revoked
  • Detectar refresh token revogado sendo usado → revogar todos os tokens desse usuario (suspeitar token roubado)
  • Ao mudar a senha: revogar todos os refresh tokens, forcar re-login
  • Redis cachea estado revoked (cenarios de acesso de alta frequencia)

Efeito: Apos logout / mudanca de senha / desabilitacao de conta o token antigo e invalido imediatamente.

Dia 7: Auditoria do Payload JWT

1 hora. Revisao de codigo de todas as chamadas sign JWT, garantir que o payload so contem identificadores nao sensiveis:

  • user_id (UUID, nao numero derivavel)
  • role (papel, sem expor estrutura organizacional)
  • exp / iat / nbf (timestamps)
  • Nao incluir: telefone / email / cartao de identificacao / cartao bancario / hash de senha / endereco

Efeito: Mesmo se o token vazar, a PII nao sera exposta.

Decisoes de Selecao de Ferramenta

Opcao A: Servicos JWT Comerciais (Auth0 / Clerk / Firebase Auth / AWS Cognito)

Melhor para: Equipes medias-grandes / autenticacao unificada multi-produto / conformidade rigorosa (financas / saude).

Vantagens: Seguranca madura / padrao OAuth 2.0 + OIDC / rotacao de refresh token incorporada / blacklist incorporada / auditoria de conformidade. Desvantagens: Preco alto (Auth0 MAU > 1000 comeca em $240/mes), vendor lock-in, auto-hospedagem dificil.

Opcao B: Auto-implementar com Bibliotecas JWT Maduras (PyJWT / jsonwebtoken / java-jwt)

Melhor para: Individual / equipe pequena / startup / MVP.

Vantagens: Gratis / flexivel / totalmente controlavel / compativel com padrao. Desvantagens: Auto-implementar revoke / rotacao (facil de bug), precisa auto-implementar plano de protecao 7 dias, sem auditoria incorporada.

Opcao C: Decodificador JWT Piick

Melhor para: Qualquer cenario de debug / auditoria / aprendizagem.

100% local sem upload, especialmente adequado para verificar tokens suspeitos em tempo de debug / auditar payload JWT / aprender estrutura JWT:

  • Decodificar header + payload (base64url decodificacao em um clique, mostrar JSON em texto plano)
  • Parsear exp / iat / nbf / aud / iss / sub (mostrar contagem regressiva de expiracao, marcar vermelho ja expirado)
  • Verificar existencia de assinatura + algoritmo (avisar alg=none)
  • Verificacao de seguranca de kid / jku / x5u (avisar campos suspeitos)
  • Nao armazena nada (decodificacao local, destruir ao fechar a pagina)

Arvore de decisao:

  • Medio-grande / multi-produto / conformidade → Opcao A (Auth0 / Clerk)
  • Individual / equipe pequena / MVP → Opcao B (biblioteca madura + plano de protecao 7 dias)
  • Qualquer debug / auditoria → Opcao C (Piick decodificacao local)

Praticas Recomendadas

  • Sempre forcar whitelist de algoritmo JWT (algorithms: ['HS256'] ou ['RS256']), sempre rejeitar alg=none
  • Sempre verificar exp (explicito ignoreExpiration: false), access token ≤ 15 minutos
  • Nunca coloque PII no payload JWT (sem telefone / email / cartao de identificacao / cartao bancario)
  • Sempre colocar JWT secret em env vars + .gitignore, nunca hardcode para Git
  • Sempre usar biblioteca JWT madura (PyJWT / jsonwebtoken / java-jwt), nao implementar verify voce mesmo
  • Sempre usar rotacao de refresh token + blacklist, access token ≤ 15 minutos + refresh token ≤ 7 dias + rotacao
  • Sempre kid whitelist de caracteres (apenas permitir [A-Za-z0-9_-]), rejeitar campos jwk / jku / x5u proprios do token
  • Sempre testar ataque de remocao de assinatura: token = "header.payload." deve ser rejeitado
  • Use Decodificador JWT Piick localmente decodifica tokens suspeitos verifica header / payload / exp / assinatura, nao consome tokens sem upload de log (dados 100% locais), Formatador JSON Piick embeleza estrutura JSON do payload JWT valida schema, Testador de Regex Piick escreve regex valida formato de claim JWT (iat e numero, exp e numero, sub e UUID), Codificador/Decodificador URL Piick verifica se URL de callback OAuth contem token em query string, Gerador Cron Piick gera programacao de rotacao JWT — conjunto de 5 pecas cobre todos os cenarios dev JWT online / debug / seguranca, dados 100% locais sem upload

JWT nao e criptografia e codificacao, a assinatura so pode evitar manipulacao nao pode manter segredo. A verdadeira “seguranca JWT” = forcar whitelist de algoritmo + verificar exp + sem PII + secret via env vars + kid whitelist + assinatura deve verificar + rotacao de refresh token + blacklist. Salve nos favoritos o Decodificador JWT Piick — verificacao em tempo de debug de tokens suspeitos em 1 minuto, dev diario nao se preocupa mais com vazamentos JWT.