Volver al blog
tutorial 2026-06-14

Un depurador JWT privacy-safe que nunca envía tu token (2026)

Un depurador JWT privacy-safe que nunca envía tu token

Estás depurando un flujo OAuth a las 11 PM, sacas un JWT de tu pestaña Network para confirmar que un claim está fijado correctamente, lo pegas en el primer decodificador JWT que Google te muestra, y un momento después recuerdas que acabas de dar a un sitio web de terceros un token de acceso funcional firmado por tu identity provider de producción — completamente capaz de logearse en la cuenta de tu cliente, llamar a tu API interna y leer lo que sea que los scopes del token permitan.

Casi cada decodificador JWT popular en la web pública — jwt.io, jwtdecoder.net, los docenas de clones — postea tu token pegado a un servidor antes de mostrarte qué hay dentro. Sus páginas de privacidad dicen "no lo almacenamos" que puede incluso ser cierto, pero el token aún cruzó el internet abierto, golpeó un endpoint HTTPS de terceros y vivió en su log de acceso HTTP por algún período de retención. Para tokens de producción, eso es un incidente de seguridad que vale la pena divulgar.

Esta guía explica cómo funcionan realmente los JWTs, qué "decodificar" un JWT realmente hace y cómo depurarlos con seguridad usando el Decodificador JWT de Ai2Done que corre 100 % en tu pestaña del navegador.

TL;DR

  • Un JWT son solo tres strings base64 separados por puntos — header, payload y signature.
  • "Decodificar" un JWT es solo decodificar base64 las primeras dos partes. No es verificación de firma.
  • La mayoría de los decodificadores JWT online postean tu token a su servidor. Incluso si dicen que no lo loguean, el token aún abandonó tu máquina y entró en un log de acceso en algún sitio.
  • El Decodificador JWT de Ai2Done corre enteramente en tu navegador — tu token nunca abandona tu pestaña.
  • Para tokens de producción con privilegios reales, este es el único patrón seguro. Trata cada pegado de un JWT de producción en una herramienta de terceros como si hubieras entregado la contraseña a alguien.

Por qué esto es más difícil de lo que parece

Un JWT (JSON Web Token, RFC 7519) es estructuralmente trivial:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJleHAiOjE3NTAwMDAwMDB9.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

Son tres partes separadas por .:

  1. Header (eyJhbGciOiJIUzI1NiJ9) — JSON base64-codificado {"alg":"HS256"} describiendo el algoritmo de firma.
  2. Payload (eyJzdWIi...) — JSON base64-codificado con los claims reales (sub, exp, campos custom).
  3. Signature (dBjftJeZ...) — HMAC o RSA/ECDSA sobre header.payload, usado para verificar integridad.

"Decodificar" un JWT significa decodificar en base64 las partes 1 y 2 para leer el JSON dentro. Esto requiere ninguna clave secreta, ninguna llamada de red, ningún servidor. Es una función JavaScript de 5 líneas. Sin embargo, el 99 % de los decodificadores JWT online insisten en hacer round-trip de tu token a través de su backend, lo que significa que el token entra en:

  • El log de terminación HTTPS de su servidor
  • El log de acceso de su reverse proxy
  • Posiblemente su log de aplicación (dependiendo de cómo lo implementen)
  • Los logs de edge de su CDN (Cloudflare, Fastly, etc.)
  • Los logs correspondientes de cualquier ad networks partner, servicios de error tracking o analytics providers cargados en la página

Incluso con las mejores intenciones del lado del operador, tu token de producción está ahora persistido en 4-6 archivos de log diferentes a través de 2-3 empresas diferentes, por períodos de retención que van de 7 días a "para siempre". Un atacante determinado comprometiendo cualquiera de esos targets tiene un bearer token funcional a los recursos de tu cliente.

Esto no es paranoia. Es threat modelling estándar para cualquiera manejando credenciales de producción.

Método 1: Ai2Done JWT Decoder (lado del navegador, la forma correcta)

El Decodificador JWT de Ai2Done son 200 líneas de JavaScript vanilla corriendo en tu pestaña del navegador. Pega un token, ve qué hay dentro, cierra la pestaña, y el token se ha ido para siempre. El flujo:

  1. Abre /tools/jwt_decoder en cualquier navegador.
  2. Pega tu JWT en el área de entrada.
  3. El header y payload decodificados aparecen instantáneamente en paneles JSON con syntax highlighting.
  4. Opcionalmente, pega tu secreto de firma (HS256) o clave pública (RS256) para verificar la firma localmente. La verificación también corre enteramente del lado del cliente.

Lo que obtienes out of the box:

  • Decodificación de header con algoritmo y key ID
  • Decodificación de payload con todos los claims custom y claims estándar (iss, sub, aud, exp, nbf, iat, jti)
  • Timestamps legibles para humanosexp: 1750000000 también se muestra como "en 47 minutos" para que puedas ver inmediatamente si el token está expirado o cerca de expirar
  • Advertencias de validación de claims — si exp está en el pasado, el campo se resalta en rojo; si aud no coincide con un valor que esperas, puedes pegar el aud esperado para comparación instantánea
  • Verificación de firma — pega tu secreto HS256, clave pública RS256 (PEM) o JWKS URI, y la herramienta te dice si la firma es válida. La verificación usa Web Crypto API enteramente in-browser.

El bundle completo es ~40 KB. Carga en <1 segundo en cualquier dispositivo, funciona offline una vez cacheado y tiene cero llamadas de red tras la carga inicial de la página.

Método 2: Un script de 5 líneas en tu terminal

Para developers que ya trabajan en terminal, el decodificador JWT más simple posible es una línea de bash:

echo "YOUR_JWT_HERE" | cut -d. -f2 | base64 -d 2>/dev/null | jq .

Esto:

  1. Pipea el JWT a cut para agarrar la segunda parte (payload)
  2. Lo decodifica en base64 (2>/dev/null silencia las advertencias de padding)
  3. Pretty-printea con jq

Para el header, reemplaza f2 con f1. Para verificación de firma, usa una librería real — python -c "import jwt; print(jwt.decode(...))" o el equivalente en tu lenguaje. No intentes implementar verificación HMAC-SHA256 en bash.

Esta es la respuesta correcta para "estoy SSHeado a un servidor y necesito inspeccionar un token ahora mismo". Es overkill si ya estás en un navegador.

Método 3: Una app nativa macOS / Windows

Para gente que odia las herramientas del navegador, hay varios decodificadores JWT offline-only:

  • macOS: JWT Inspector (gratis, de la App Store)
  • Windows: JWT Decoder por IDESoft (gratis, de MS Store)
  • Multiplataforma: extensión de VS Code "JWT Debugger" (funciona dentro de tu editor)

Todos corren enteramente en tu dispositivo sin requests de red. Elige el que encaje con tu flujo.

Cómo lo construimos (deep-dive técnico)

El Decodificador JWT de Ai2Done es deliberadamente mínimo:

  • Sin frameworks — JS vanilla, ~200 líneas, ~40 KB gzipped. Carga instantáneamente incluso en una conexión 3G.
  • Sin analytics, sin telemetría — ni siquiera sabemos cuánta gente lo usa, por diseño. Las page views se registran a nivel de ruta (/tools/jwt_decoder recibió X visitas) pero nunca con información derivada del token.
  • base64url-safe por defecto — los JWTs usan la variante URL-safe de base64 (-_ en vez de +/); manejamos ambas.
  • Web Crypto para verificación de firmacrypto.subtle.verify() soporta nativamente HMAC-SHA256/384/512 y RS256/384/512. ES256/384 (ECDSA) también funciona en navegadores modernos. PS256 (RSA-PSS) requiere un pequeño shim JS porque algunos navegadores antiguos carecen de ello.
  • Soporte JWKS — pega un URI JWKS (p. ej. https://accounts.google.com/.well-known/jwks.json), la herramienta fetchea el JWK set, encuentra la clave que coincide con el kid del token y verifica la firma. El fetch sucede desde tu navegador directamente al IdP, nunca a través de nosotros.

La única decisión de diseño que vale la pena destacar: deliberadamente no ofrecemos funcionalidad "firma un JWT". La herramienta es read-only. Firmar requiere una clave secreta, y no queremos a los usuarios en el hábito de pegar su secreto HMAC o clave privada RSA en apps web. Firma tus tokens con una librería real en el código de tu aplicación; usa esta herramienta para verificar lo que salió.

FAQ

Q: ¿"Decodificar" un JWT es un riesgo de seguridad por sí mismo? A: No — decodificar en base64 el header y payload revela solo lo que el issuer eligió poner ahí. La spec JWT es explícita: el payload está base64-codificado, no encriptado. Cualquiera que tenga el token puede leer qué hay dentro. El riesgo real es dejar que el token mismo se filtre, porque el token es un credential bearer — quien lo tenga puede usarlo.

Q: El exp de mi token está en el pasado pero la API aún lo acepta. ¿Por qué? A: Algunas razones posibles: (1) el servidor está verificando un claim de timestamp diferente como nbf o iat e ignorando exp, (2) el servidor tiene clock skew y acepta tokens hasta N minutos después de expirar, (3) el tipo de token es realmente un refresh token que no expira tan rápido como los access tokens, o (4) la API genuinamente tiene un bug. Verifica la política de validación de tu IdP.

Q: ¿Cómo verifico la firma sin la clave pública del IdP? A: No puedes, por diseño — ese es el punto. La firma prueba que el token fue emitido por alguien que conocía el secreto de firma. Si no tienes la clave pública (para RS256) o el secreto compartido (para HS256), no puedes verificar integridad. El decodificador te dirá "unverified — provide a key to verify". Esto es comportamiento correcto.

Q: ¿Por qué la herramienta muestra algunos claims como estándar y otros como custom? A: RFC 7519 reserva un set de nombres de claim estándar: iss, sub, aud, exp, nbf, iat, jti. Cualquier otra cosa es custom (p. ej. name, email, roles, claims específicos de aplicación). El decodificador resalta los claims estándar con sus semánticas RFC-definidas y trata todo lo demás como JSON de forma libre.

Q: ¿Puedo decodificar un token JWE encriptado? A: No sin la clave de descifrado. JWE (JSON Web Encryption, RFC 7516) está genuinamente encriptado, así que su payload es opaco sin la clave. La herramienta detecta JWE vs JWS basándose en el claim enc del header y te dice que no puede decodificar tokens encriptados sin una clave (y no ofrecemos pegado de clave porque esa es una operación sensible que debería suceder en tu propio código, no en una herramienta web).

Q: ¿La herramienta funciona offline? A: Sí. Tras la primera visita, la herramienta está en el cache HTTP de tu navegador y funciona sin acceso a internet — útil al depurar tokens en entornos airgapped o cuando tu red está caída.

Pruébalo ahora

Depura tu JWT sin dárselo a un desconocido:

Abre el Decodificador JWT →

Pega, ve, cierra. Tu token nunca abandona tu pestaña.

Lecturas relacionadas


Última actualización 2026-06-14. El Decodificador JWT corre 100 % en tu pestaña del navegador — tus tokens nunca abandonan tu dispositivo. No tenemos log de servidor, no analytics sobre contenido de token y no hay forma de recuperar un token decodificado tras cerrar la pestaña.