FlawOpen

flawopen.com/Teardowns/cve-2026-105752-vllm-harmony-cache-salt-omission

● CVE-2026-105752 · CVSS 3.1 · Низкий
Исследования · FlawOpen

CVE-2026-105752: пропуск cache_salt в vLLM

Продолжение инструмента GPT-OSS в Responses API vLLM могло пропустить cache_salt и использовать пространство кэша префиксов без соли. Обновите vLLM до 0.30.0 или новее и сохраняйте соль арендатора во всех продолжениях.[1], [5]

💡 Простыми словами (ELI5)

Представьте документы каждого клиента в шкафчиках с личной цветной меткой. Первый запрос получает нужную метку, но инструмент теряет её, возвращая документы для следующего шага. Общая полка может сигнализировать попаданием в кэш, что предполагаемые страницы уже есть; сами страницы она не выдаёт.[1]

Ключевые понятия и термины

Prefix caching
Повторно использует блоки ключ/значение для одинаковых префиксов.[6]
cache_salt
Значение в хеше первого блока для разделения кэшей с разными солями.[6]
Harmony continuation
Следующий ввод модели после ответа Harmony, в том числе после инструмента.[1]
Membership oracle
Сигнал наличия предполагаемого префикса без раскрытия содержимого.[1]
CWE-524
Использование кэша с чувствительными данными; основная классификация предупреждения.[1]

Связи со стандартами

  • Ссылка CWE для слабого места, описанного в этом руководстве: CWE-524

Анализ первопричины

Предупреждение vLLM описывает GPT-OSS Harmony для POST /v1/responses. Начальный ввод передавал request.cache_salt в tokens_input; после встроенного инструмента или MCP продолжение вызывало tokens_input(token_ids) без соли. Helper сохраняет соль только при её передаче. При автоматическом кэшировании префиксов в общей среде продолжение использовало пространство без соли. В предупреждении указаны версии до 0.30.0, поведение подтверждено на 0.25.1, а нижняя граница не установлена. Результат — сигнал о наличии префикса через cached_tokens_per_turn, а не прямое раскрытие произвольного текста запроса. CWE-200 также указан как воздействие; здесь CWE-524 — единственная основная слабость.[1], [3], [4]

Пошаговый сценарий атаки

Шаг 1

Общий сервис соответствует предварительным условиям

Нужны затронутая версия, GPT-OSS Harmony Responses, кэш префиксов и инструмент; жертва задаёт cache_salt и достигает продолжения.[1]

Шаг 2

Первый ввод движка получает соль

Первый вызов tokens_input включает request.cache_salt и помещает префикс в пространство вызывающей стороны с солью.[1]

Шаг 3

Продолжение инструмента теряет соль

После результата инструмента продолжение вызывает tokens_input(token_ids) без исходной соли; префикс может попасть в общее пространство без соли.[1]

Шаг 4

Счётчик кэша может раскрыть наличие префикса

Соседний арендатор, восстановивший префикс, может проверить cached_tokens_per_turn и определить его наличие, но не получить произвольный текст запроса.[1]

Шаг 5

Renderer сохраняет соль в каждом ходе

Влитая переработка renderer сохраняет cache_salt при рендеринге Harmony и передаёт его каждому новому вводу движка; обновитесь до 0.30.0+.[1], [3], [7]

Исходный код: Уязвимый vs Защищённый вариант

Предупреждение vLLM описывает GPT-OSS Harmony для POST /v1/responses. Начальный ввод передавал request.cache_salt в tokens_input; после встроенного инструмента или MCP продолжение вызывало tokens_input(token_ids) без соли. Helper сохраняет соль только при её передаче. При автоматическом кэшировании префиксов в общей среде продолжение использовало пространство без соли. В предупреждении указаны версии до 0.30.0, поведение подтверждено на 0.25.1, а нижняя граница не установлена. Результат — сигнал о наличии префикса через cached_tokens_per_turn, а не прямое раскрытие произвольного текста запроса. CWE-200 также указан как воздействие; здесь CWE-524 — единственная основная слабость. Upstream excerpts, not a literal line-by-line diff.[1], [3], [4], [7]

Фрагмент исходного кода: renderer Harmony Responses API vLLM (фрагменты разных версий)

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
# В исходном пути запроса использовался salt, а в продолжении после вызова инструмента — нет.
engine_input = tokens_input(token_ids, cache_salt=request.cache_salt)

# После результата инструмента продолжение заново формировало входные данные так:
engine_input = tokens_input(token_ids)
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
# Сохранять salt запроса в контексте рендеринга Harmony.
cache_salt = cast(str | None, engine_input.get("cache_salt"))
engine_input = self.online_renderer.render_responses_harmony_messages(
    context.messages,
    cache_salt=cache_salt,
    tok_params=tok_params,
)

# Средство рендеринга передаёт salt при каждом создании входных данных движка.
engine_input = tokens_input(prompt["prompt_token_ids"], cache_salt=cache_salt)

Чек-лист по защите системы для инженеров

Источники