FlawOpen

flawopen.com/Teardowns/cve-2026-61500-rejetto-hfs-predictable-session-key

● CVE-2026-61500 · CVSS 9.3[1] · Critical
FlawOpen Security Research

CVE-2026-61500: Rejetto HFS Predictable Session Signing Key

Rejetto HFS 3.0.0–3.2.0 used Math.random-derived values for session signing and login. Horizon3 reports that the leak enabled session forgery; VulnCheck says exploitation activity was observed from October 1. Upgrade to 3.2.1+; no specific victim compromise is confirmed.[1], [4], [5]

💡 Plain English Explainer (ELI5)

A cookie signature is like a wax seal on an administrator pass. HFS used a seal-making secret drawn from a predictable number stream, while the login flow revealed more numbers from that same stream. If someone can infer the secret, they can counterfeit the seal. The patch switches the secret to Node.js cryptographic randomness.[1], [3]

Core Concepts & Subsystem Terms

Session-signing key
A secret used by Koa to sign session cookies so tampering can be detected.[1], [3]
Math.random()
A general-purpose pseudorandom API, not a cryptographic source for secrets. Horizon3 describes the relevant V8 generator outputs as reversible when enough related outputs are visible.[6], [4]
CWE-338
Use of a cryptographically weak pseudorandom number generator; this is the weakness mapped in the CVE record.[1], [6]
PRNG state
The internal state that determines future pseudorandom outputs. Reusing one generator for a secret and observable values can expose relationships between them.[4]
Discovery context
Horizon3 says its Mythos-assisted research harness identified and validated this HFS vulnerability chain. This describes the researchers’ discovery process; it is not a vulnerability in Mythos or evidence that AI autonomously attacked a real HFS deployment.[4]

Framework mappings

  • CWE reference for the weakness described in this guide: CWE-338

Root Cause Analysis

The CVE record identifies HFS 3.0.0 through 3.2.0 and CWE-338. In upstream commit 59472e5, the vulnerable startup code supplied Koa with [randomId(30)]; randomId() used Math.random(). The same commit changes this to [randomBytes(32).toString('base64url')], sourced from node:crypto. It also changes the public login handshake identifier from Math.random() to randomUUID(). Horizon3 reports that unauthenticated login responses exposed enough related Math.random() output to reconstruct the V8 PRNG state and derive the cookie-signing key. With a forged admin session, built-in HFS administrative functionality could lead to server-side code execution. This article describes the published chain at a high level and does not reproduce its solver, requests, or payloads. VulnCheck says its Canary Intelligence began observing exploitation on October 1, 2026, in a report published October 2; this telemetry does not identify a compromised HFS deployment.[1], [3], [4], [5]

Step-by-Step Attack Flow

Step 1

A vulnerable HFS release is exposed

The affected range is HFS 3.0.0 through 3.2.0. The CVE is remotely reachable without prior privileges, according to its CVSS metrics.[1], [2]

Step 2

The same weak random stream serves two roles

HFS derived the cookie-signing key from Math.random() and the login flow disclosed related outputs. A cryptographic secret should not come from a predictable or observable general-purpose PRNG.[1], [3]

Step 3

The weakness crosses the session boundary

Horizon3 reports that the outputs made PRNG state recovery feasible, enabling session-signature forgery and administrator access. The detailed recovery procedure is intentionally omitted.[4]

Step 4

Administrative access can reach server-side execution

Horizon3 documents a chain from forged administrator session to HFS server_code functionality. VulnCheck says its Canary Intelligence began observing exploitation on October 1, 2026, as reported on October 2; telemetry does not establish compromise of a specific installation.[4], [5]

Source Code: Flaw vs. Secure Implementation

These excerpts reflect the actual upstream commit. randomBytes(32) supplies 256 bits from Node.js crypto for the signing key; randomUUID() replaces the public login identifier source. The key fix addresses the security boundary: secrets used to authenticate sessions must come from a cryptographic random source and remain independent of observable application PRNG output. Upgrade to HFS 3.2.1 or a later supported release; this excerpt is explanatory, not a standalone patch. This secures the generated fallback only: if COOKIE_SIGN_KEYS is configured, each supplied key must also be independently generated with cryptographic randomness, kept secret, and rotated if exposed.[3], [1]

Source excerpt: src/index.ts (cookie-signing key) and src/api.auth.ts (login handshake ID), upstream commit 59472e5

UNPATCHED FLAW
import { httpStream, randomId } from './misc'

const keys = process.env.COOKIE_SIGN_KEYS?.split(',')
  || [randomId(30)]
export const app = new Koa({ keys })

// Login handshake identifier
const sid = Math.random()
HARDENED SECURE PATCH
import { randomBytes, randomUUID } from 'node:crypto'

const keys = process.env.COOKIE_SIGN_KEYS?.split(',')
  || [randomBytes(32).toString('base64url')]
export const app = new Koa({ keys })

// Login handshake identifier
const sid = randomUUID()

Engineering & System Hardening Checklist

Sources