¿Puede Snyk detectar problemas de seguridad en JWT?
4 de marzo de 2025
0 minutos de lecturaLos desarrolladores suelen usar JWT para implementar autenticación en lugar de las sesiones tradicionales basadas en cookies. Pero ¿qué sucede cuando no comprenden bien la seguridad de JWT y se exponen a una vulnerabilidad grave de autenticación comprometida?
¿Qué es un JWT?
Los JSON Web Tokens (JWT) son una forma compacta y autónoma de transmitir información de manera segura entre partes como un objeto JSON. Como cuentan con una firma digital, que suele generarse mediante certificados, esta información se puede verificar y considerar confiable. Los desarrolladores web suelen recurrir a los JWT para agregar autenticación a sus aplicaciones y evitar la seguridad tradicional de las cookies del navegador y la gestión de sesiones.
Estructura de un JWT
Como se mencionó anteriormente, un JWT es un objeto JSON común que almacena datos. Un JWT consta de un encabezado, una carga útil y una firma. Estos componentes se codifican en Base64 y se concatenan con puntos (.) para formar la cadena del JWT.
1. Encabezado: El encabezado suele constar de dos partes: el tipo de token, JWT, y el algoritmo de firma que se usa, como HMAC SHA256 o RSA.
2. Carga útil: La carga útil contiene las declaraciones. Estas son afirmaciones sobre una entidad (por lo general, el usuario) y datos adicionales. Sin embargo, evita almacenar información sensible y confidencial, ya que los JWT suelen no estar cifrados y cualquiera puede decodificarlos para acceder a los datos. Hay tres tipos de declaraciones: registradas, públicas y privadas.
3. Firma: Para crear la firma, debes tomar el encabezado codificado, la carga útil codificada, un secreto y el algoritmo especificado en el encabezado, y firmarlos.
El JWT resultante podría verse así:
El papel de JWT en las API y los microservicios
Los JWT cumplen una función importante para los desarrolladores de frontend y backend al implementar autenticación y crear API y microservicios. A diferencia de la autenticación tradicional basada en sesiones en el servidor, que requiere que este mantenga un estado de sesión persistente mediante una base de datos, los JWT ofrecen un enfoque más escalable y eficiente gracias a su naturaleza sin estado. Cuando un usuario inicia sesión, el servidor genera un token que codifica la información del usuario y lo firma con una clave secreta. Luego, este token se envía al cliente, que lo incluye en el encabezado de las solicitudes posteriores.
El servidor puede verificar la firma del token para autenticar al usuario sin almacenar datos de sesión. La naturaleza sin estado de los JWT los hace especialmente adecuados para sistemas distribuidos y arquitecturas de microservicios, donde mantener un almacén centralizado de sesiones podría convertirse en un cuello de botella o en un único punto de falla.
Paquetes npm de código abierto populares para JWT en Node.js
Al trabajar con JWT en Node.js, los desarrolladores tienen a su disposición diversas bibliotecas de código abierto, pero suelen elegir el popular paquete npm jsonwebtoken. Estas bibliotecas simplifican la generación, firma y verificación de tokens. Sin embargo, es fundamental comprender las diferencias entre sus funciones y sus consideraciones de seguridad para evitar usar la biblioteca de forma insegura y generar un riesgo de seguridad.
Otros paquetes npm de JSON incluyen node-jose e integraciones con frameworks web como passport-jwt y @fastify/jwt.
Riesgos de seguridad de JWT al decodificar un token
Para mostrar un error clásico al usar JWT de forma insegura para gestionar la autenticación, elegiremos las opciones populares que suelen atraer a la mayoría de los desarrolladores: el framework web Express y jsonwebtoken como biblioteca JWT.
¿Puedes encontrar la vulnerabilidad de seguridad en el siguiente código de Node.js?
Este código de Node.js usa jsonWebToken.decode() para decodificar el JWT. Este método solo decodifica el token, pero no verifica su firma. Por lo tanto, aunque funciona porque decodedToken devuelve datos, no hay garantía de que sean los mismos que estableció el servidor ni de que un tercero no los haya manipulado. Esto significa que cualquiera puede manipular el token y la aplicación seguirá aceptándolo como válido. En su lugar, usa jsonWebToken.verify() para asegurarte de que el token se decodifique y se verifique con la clave secreta.
Snyk detecta problemas de seguridad en JWT
Ejecuta el código vulnerable de Node.js anterior con Snyk. Detectará el problema de seguridad de JWT, que se debe al uso del método inseguro de JSON Web Token jwt.decode() en la biblioteca jsonwebtoken:

Snyk lo detectará según dónde lo integres. En la captura de pantalla anterior, importé el repositorio de código de GitHub mediante la aplicación web de Snyk. Una vez importado, Snyk analiza el repositorio en busca de archivos de manifiesto, como requirements.txt de Python o package.json de npm, para detectar dependencias vulnerables. Snyk también detecta archivos de IaC, como los de Terraform, y realiza un análisis estático del código para examinar el código en sí.
Como puedes ver en la captura de pantalla anterior, Snyk detectó el uso indebido del código de la biblioteca jsonwebtoken, que utiliza la función insegura jwt.decode y puede provocar una vulnerabilidad de autenticación comprometida.
A continuación, se muestra una forma recomendada de decodificar un JWT de manera segura:
Otros problemas de seguridad de JWT en el código de Node.js de ejemplo anterior incluyen las siguientes deficiencias:
Datos sensibles codificados de forma fija: El fragmento de código almacena la clave secreta mediante variables de entorno. Asegúrate de gestionar estas variables de forma segura, de que no queden expuestas en los sistemas de control de versiones y de que puedas rotarlas y administrarlas de manera segura.
Registro insuficiente: Implementa el registro de los intentos de autenticación y los errores. Esto puede ayudarte a supervisar posibles incidentes de seguridad y responder ante ellos.
Limitación de velocidad: ¿Cómo controlas los intentos de inicio de sesión por fuerza bruta y otros usos abusivos de las API de autenticación? Implementa límites de velocidad para evitar el consumo excesivo de recursos y los intentos de autenticación sin control.
Vencimiento del token: Aunque el código establece un tiempo de vencimiento para los tokens, es fundamental verificar que el token no haya vencido en cada solicitud.
Prácticas recomendadas de seguridad para JWT
Proteger una API REST con JWT implica más que emitir y verificar tokens. Requiere considerar cuidadosamente varias prácticas de seguridad para mitigar posibles vulnerabilidades. Por ejemplo, usa siempre una clave secreta segura para firmar los tokens, de preferencia claves asimétricas, y asegúrate de que se transmitan mediante HTTPS para evitar que alguien los intercepte.
Además, es fundamental implementar estrategias adecuadas de vencimiento y revocación de tokens. Los tokens deben tener una vigencia corta para minimizar el riesgo de uso indebido si se ven comprometidos. Los tokens de actualización pueden usarse para emitir nuevos tokens de acceso sin pedirle al usuario que vuelva a iniciar sesión, pero también deben gestionarse de forma segura.
Puedes consultar una guía más completa sobre cómo proteger las API REST.
SEGURIDAD DEL CÓDIGO DE IA
Guía de compra para la seguridad del código generado por IA
Aprende a proteger el código generado por IA con la Guía de compra para la seguridad del código generado por IA de Snyk.
