FlawOpen

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

● CVE-2026-61500 · CVSS 9.3[1] · 严重
安全研究 · FlawOpen

CVE-2026-61500:Rejetto HFS 可预测的会话签名密钥

Rejetto HFS 3.0.0–3.2.0 使用 Math.random() 生成会话签名和登录所用的值。Horizon3 称这些值泄露后可伪造会话;VulnCheck 称从 10 月 1 日起观察到漏洞利用活动。请升级至 3.2.1 或更高版本;目前没有证据确认某个具体受害者遭到入侵。[1], [4], [5]

💡 通俗易懂的原理解析 (ELI5)

Cookie 签名就像管理员通行证上的蜡封。HFS 用一串可预测的数字生成封印秘密,同时登录流程又泄露了同一序列中的其他数字。如果有人推导出秘密,就能仿造封印。补丁改用 Node.js 的密码学随机数。[1], [3]

核心概念与专有名词

会话签名密钥
Koa 用于签署会话 Cookie、以便检测篡改的秘密值。[1], [3]
Math.random()
通用伪随机 API,不适合生成密码学秘密。[6], [4]
CWE-338
使用密码学强度不足的伪随机数生成器;这是 CVE 记录映射的弱点。[1], [6]
PRNG 状态
决定后续伪随机输出的内部状态。同一生成器若同时用于秘密和可观察值,它们之间可能暴露关联。[4]
发现背景
Horizon3 表示,其 Mythos 辅助的多智能体研究系统发现并验证了这条 HFS 漏洞链。这描述的是研究人员发现漏洞的过程;它不是 Mythos 本身的漏洞,也不代表 AI 自主攻击了真实 HFS 实例。[4]

框架映射

  • 本指南所述弱点的 CWE 参考: CWE-338

根本原因剖析 (Root Cause)

CVE 记录将受影响版本列为 HFS 3.0.0 至 3.2.0,并映射 CWE-338。在上游提交 59472e5 中,易受攻击的代码向 Koa 提供 [randomId(30)];randomId() 使用 Math.random()。修复将其改为从 node:crypto 导入的 [randomBytes(32).toString('base64url')]。同一提交还将公开登录握手标识符从 Math.random() 改为 randomUUID()。Horizon3 报告称,未认证即可访问的登录响应泄露了足够多的相关输出,可恢复 V8 PRNG 状态并推导 Cookie 签名密钥。伪造管理员会话后,HFS 内置管理功能可能进一步导致服务器端代码执行。本文仅以高层次描述该链路,不提供求解器、请求或载荷。VulnCheck 称其 Canary Intelligence 于 2026 年 10 月 1 日开始观察到漏洞利用活动,并在 10 月 2 日发布报告;这些遥测数据没有指出任何已遭入侵的 HFS 实例。[1], [3], [4], [5]

攻击执行流程分解

步骤 1

可访问的 HFS 版本处于受影响范围

受影响范围为 HFS 3.0.0 至 3.2.0。CVSS 指标表明可通过网络触达,且无需预先权限。[1], [2]

步骤 2

同一弱随机序列承担两种用途

HFS 从 Math.random() 派生签名密钥,登录流程又泄露相关输出。密码学秘密不应来自可预测或可观察的通用 PRNG。[1], [3]

步骤 3

弱点跨越会话信任边界

据 Horizon3 称,这些输出使恢复 PRNG 状态成为可能,从而伪造会话签名并获得管理员访问权限。本文省略详细恢复过程。[4]

步骤 4

管理员权限可进一步触达服务器代码执行

Horizon3 描述了从伪造管理员会话到 HFS server_code 功能的链路。VulnCheck 称其 Canary Intelligence 于 2026 年 10 月 1 日开始观察到漏洞利用活动,相关报告于 10 月 2 日发布;这些遥测数据不能证明某个具体实例已遭入侵。[4], [5]

源代码对比:漏洞与安全实现

这些代码片段对应真实的上游提交。randomBytes(32) 从 Node.js 密码学模块生成 256 位密钥;randomUUID() 替换公开登录标识符的生成来源。用于会话认证的秘密必须来自密码学随机源,并与应用 PRNG 的可观察输出隔离。请升级到 HFS 3.2.1 或更高的受支持版本;此代码用于说明修复,不是独立补丁。 这只保护自动生成的后备值:如果配置了 COOKIE_SIGN_KEYS,每个提供的密钥也必须单独使用密码学安全随机数生成、妥善保密,并在泄露后轮换。[3], [1]

源码摘录: src/index.ts(Cookie 签名密钥)和 src/api.auth.ts(登录握手 ID,上游提交 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()

工程与系统安全加固清单

参考来源