flawopen.com/Teardowns/cve-2026-61500-rejetto-hfs-predictable-session-key
CVE-2026-61500: предсказуемый ключ подписи сессий в Rejetto HFS
Rejetto HFS 3.0.0–3.2.0 использовала значения Math.random() для подписи сессий и при входе. По данным Horizon3, утечка позволяла подделывать сессии; VulnCheck сообщает о наблюдении эксплуатации с 1 октября. Обновитесь до 3.2.1 или новее; компрометация конкретной жертвы не подтверждена.[1], [4], [5]
Подпись 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 и не доказательство автономной атаки ИИ на реальную установку HFS.[4]
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-338
Анализ первопричины
В записи CVE указаны HFS 3.0.0–3.2.0 и CWE-338. В upstream-коммите 59472e5 уязвимый код передавал Koa [randomId(30)]; randomId() использовал Math.random(). Исправление заменило это на [randomBytes(32).toString('base64url')] из node:crypto. В том же коммите публичный идентификатор рукопожатия при входе заменён с Math.random() на randomUUID(). Horizon3 сообщает, что доступные без аутентификации ответы входа раскрывали достаточно связанных выходов для восстановления состояния PRNG V8 и вычисления ключа подписи cookie. Поддельная сессия администратора открывала встроенные функции администрирования HFS, способные привести к выполнению кода на сервере. Здесь цепочка описана на высоком уровне без решателя, запросов и полезных нагрузок. По данным VulnCheck, Canary Intelligence начала наблюдать эксплуатационную активность 1 октября 2026 года; об этом сообщалось в отчёте от 2 октября. Телеметрия не указывает на конкретную скомпрометированную установку HFS.[1], [3], [4], [5]
Пошаговый сценарий атаки
Слабость преодолевает границу сессии
По данным Horizon3, выходные значения позволяли восстановить состояние PRNG и подделать подпись сессии для получения доступа администратора. Подробный метод восстановления не приводится.[4]
Доступ администратора может привести к запуску кода
Horizon3 описывает цепочку до функции HFS server_code. По данным VulnCheck, Canary Intelligence начала наблюдать эксплуатационную активность 1 октября 2026 года, о чём сообщалось 2 октября; эта телеметрия не доказывает компрометацию конкретной установки.[4], [5]
Исходный код: Уязвимый vs Защищённый вариант
Фрагменты соответствуют реальному upstream-коммиту. randomBytes(32) даёт ключу 256 бит из криптографического модуля Node.js, а randomUUID() заменяет источник публичного идентификатора входа. Секреты для аутентификации сессий должны поступать из криптографического источника и не зависеть от наблюдаемых выходов прикладного PRNG. Обновитесь до HFS 3.2.1 или более новой поддерживаемой версии; это пояснение, а не отдельный патч. Это защищает только сгенерированное резервное значение: если задан COOKIE_SIGN_KEYS, каждый переданный ключ также нужно независимо создать криптографически стойким генератором, хранить в секрете и заменить при раскрытии.[3], [1]
Фрагмент исходного кода: src/index.ts (ключ подписи cookie) и src/api.auth.ts (идентификатор рукопожатия входа, коммит 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()
Чек-лист по защите системы для инженеров
- ✓Обновите HFS 3.0.0–3.2.0 до 3.2.1 или новее; предпочтительна последняя поддерживаемая стабильная версия.[2], [1]
- ✓Проведите инвентаризацию всех экземпляров HFS, включая Windows-хосты, контейнеры, тестовые серверы и доступные из интернета файловые ресурсы; запишите версии и доступность.[4]
- ✓Если немедленное обновление невозможно, ограничьте доступ доверенными сетями и уберите публичную доступность до обновления. Это уменьшает экспозицию, но не устраняет слабую генерацию ключа.[4]
- ✓После обновления любого экземпляра, который был общедоступен во время уязвимости, аннулируйте все существующие сеансы и замените заданный
COOKIE_SIGN_KEYS; если проверка выявит несанкционированные действия администратора, смените и учетные данные администратора. Сохраните журналы для анализа.[1], [4] - ✓Считайте наблюдаемое зондирование поводом для расследования, а не доказательством компрометации. Сохраните журналы и проверьте несанкционированные изменения конфигурации и запуск кода.[5], [4]
- ✓В приложениях Node.js проверьте, что каждое заданное значение
COOKIE_SIGN_KEYSнезависимо создано криптографически стойким генератором, хранится в секрете и заменяется при раскрытии; безопасное резервное значение не проверяет переопределения. Для других секретов используйте APInode:crypto, напримерrandomBytes(). Не создавайте ключи подписи, токены сброса или значения авторизации изMath.random().[3], [6]