flawopen.com/Teardowns/cve-2026-61500-rejetto-hfs-predictable-session-key
CVE-2026-61500: clave predecible para firmar sesiones en Rejetto HFS
Rejetto HFS 3.0.0–3.2.0 usaba valores derivados de Math.random() para firmar sesiones y en el inicio de sesión. Horizon3 informa que la exposición permitía falsificarlas; VulnCheck dice que observó actividad de explotación desde el 1 de octubre. Actualice a 3.2.1 o posterior; no se ha confirmado el compromiso de una víctima concreta.[1], [4], [5]
La firma de una cookie es como el sello de cera de una credencial administrativa. HFS generaba el secreto del sello a partir de una secuencia numérica predecible, mientras el inicio de sesión mostraba otros números de esa misma secuencia. Si alguien deduce el secreto, puede falsificar el sello. El parche usa aleatoriedad criptográfica de Node.js.[1], [3]
Conceptos Clave y Términos
Clave de firma de sesión- Secreto que Koa usa para firmar cookies de sesión y detectar manipulaciones.[1], [3]
Math.random()- API seudoaleatoria de propósito general, inadecuada para crear secretos criptográficos.[6], [4]
CWE-338- Uso de un generador seudoaleatorio criptográficamente débil; es la debilidad asignada en el registro CVE.[1], [6]
Estado del PRNG- Estado interno que determina las siguientes salidas seudoaleatorias. Reutilizar el generador para un secreto y valores observables puede revelar relaciones entre ellos.[4]
Contexto del descubrimiento- Horizon3 afirma que su sistema de investigación multiagente, asistido por Mythos, identificó y validó esta cadena de vulnerabilidades de HFS. Esto describe cómo los investigadores encontraron el fallo; no es una vulnerabilidad de Mythos ni prueba de un ataque autónomo de IA contra una instalación real.[4]
Mapeos de marcos
- Referencia CWE para la debilidad descrita en esta guía: CWE-338
Análisis de Causa Raíz
El registro CVE identifica HFS 3.0.0–3.2.0 y CWE-338. En el commit upstream 59472e5, el código vulnerable proporcionaba a Koa [randomId(30)]; randomId() usaba Math.random(). La corrección lo cambia por [randomBytes(32).toString('base64url')], importado de node:crypto. El mismo commit sustituye Math.random() por randomUUID() para el identificador público del inicio de sesión. Horizon3 informa que las respuestas de inicio de sesión accesibles sin autenticación exponían suficientes salidas relacionadas para recuperar el estado del PRNG de V8 y derivar la clave de firma de cookies. Con una sesión de administrador falsificada, las funciones administrativas integradas podían conducir a ejecución de código en el servidor. Este artículo resume la cadena sin reproducir el solucionador, las solicitudes ni los payloads. VulnCheck indica que Canary Intelligence empezó a observar actividad de explotación el 1 de octubre de 2026, según un informe publicado el 2 de octubre; esa telemetría no identifica una instalación HFS comprometida.[1], [3], [4], [5]
Flujo de Ataque Paso a Paso
La debilidad cruza la barrera de sesión
Horizon3 informa que las salidas permitían recuperar el estado del PRNG, lo que posibilitaba falsificar la firma de sesión y obtener acceso administrativo. Se omite el procedimiento detallado de recuperación.[4]
El acceso administrativo puede llegar a ejecutar código
Horizon3 documenta la cadena desde la sesión falsificada hasta la función server_code de HFS. VulnCheck indica que Canary Intelligence empezó a observar actividad de explotación el 1 de octubre de 2026, según el informe del 2 de octubre; esa telemetría no demuestra el compromiso de una instalación concreta.[4], [5]
Código Fuente: Vulnerable vs. Seguro
Estos fragmentos reflejan el commit upstream real. randomBytes(32) proporciona 256 bits del módulo criptográfico de Node.js para la clave; randomUUID() reemplaza la fuente del identificador público de inicio de sesión. Los secretos que autentican sesiones deben venir de una fuente criptográfica y ser independientes de las salidas observables del PRNG de la aplicación. Actualiza a HFS 3.2.1 o una versión posterior compatible; este fragmento explica el cambio, no es un parche autónomo. Esto protege únicamente el valor de respaldo generado: si se configura COOKIE_SIGN_KEYS, cada clave proporcionada también debe generarse de forma independiente con aleatoriedad criptográfica, mantenerse en secreto y rotarse si queda expuesta.[3], [1]
Fragmento de origen: src/index.ts (clave de firma de cookies) y src/api.auth.ts (ID del handshake de inicio de sesión, commit upstream 59472e5)
import { httpStream, randomId } from './misc'
const keys = process.env.COOKIE_SIGN_KEYS?.split(',')
|| [randomId(30)]
export const app = new Koa({ keys })
const sid = Math.random()
import { randomBytes, randomUUID } from 'node:crypto'
const keys = process.env.COOKIE_SIGN_KEYS?.split(',')
|| [randomBytes(32).toString('base64url')]
export const app = new Koa({ keys })
const sid = randomUUID()
Lista de Verificación de Seguridad para Ingeniería
- ✓Actualiza HFS 3.0.0–3.2.0 a 3.2.1 o posterior; da preferencia a la versión estable compatible más reciente.[2], [1]
- ✓Inventaría todas las instancias de HFS, incluidos hosts Windows, contenedores, pruebas y servicios de archivos expuestos a Internet; registra versión y exposición.[4]
- ✓Si no puedes actualizar de inmediato, limita el acceso a redes de confianza y elimina la exposición pública mientras preparas la actualización. Esto reduce la exposición, pero no corrige la generación débil de claves.[4]
- ✓Después de actualizar cualquier instancia que estuviera accesible públicamente mientras era vulnerable, invalida todas las sesiones existentes y rota cualquier
COOKIE_SIGN_KEYSconfigurada; si la investigación encuentra actividad administrativa no autorizada, rota también las credenciales de administrador. Conserva los registros para revisarlos.[1], [4] - ✓Considera los sondeos observados un motivo para investigar, no una prueba de compromiso. Conserva los registros y busca cambios de configuración o ejecución no autorizados.[5], [4]
- ✓En aplicaciones Node.js, comprueba que cada valor configurado en
COOKIE_SIGN_KEYSse haya generado de forma independiente con aleatoriedad criptográfica, se mantenga en secreto y se rote si queda expuesto; el valor de respaldo seguro no valida las anulaciones. Para otros secretos, usa API denode:crypto, comorandomBytes(). Nunca derives claves de firma, tokens de restablecimiento ni valores de autorización deMath.random().[3], [6]