FlawOpen

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

● CVE-2026-105752 · CVSS 3.1 · Baixa
Pesquisa · FlawOpen

CVE-2026-105752: omissão de cache_salt no vLLM

Uma continuação de ferramenta GPT-OSS no Responses do vLLM podia omitir o cache_salt e usar um espaço de cache de prefixo sem salt. Atualize para vLLM 0.30.0 ou posterior e preserve salts por tenant em todas as continuações.[1], [5]

💡 Explicação em Linguagem Simples (ELI5)

Imagine documentos de cada cliente em armários com etiquetas coloridas privadas. A primeira solicitação recebe a etiqueta correta, mas uma ferramenta a perde ao devolver os documentos para a etapa seguinte. Uma prateleira compartilhada pode indicar se páginas adivinhadas já estão lá por um acerto de cache; ela não entrega as páginas.[1]

Conceitos Centrais e Termos

Prefix caching
Reutiliza blocos chave/valor do modelo para prefixos iguais.[6]
cache_salt
Valor misturado ao hash do primeiro bloco para separar caches com salts distintos.[6]
Harmony continuation
Entrada seguinte do modelo após resposta Harmony, inclusive após ferramenta.[1]
Membership oracle
Sinal de presença de um prefixo suposto sem revelar o conteúdo.[1]
CWE-524
Uso de cache com informação sensível; classificação principal do aviso.[1]

Mapeamentos de frameworks

  • Referência CWE para a fraqueza descrita neste guia: CWE-524

Análise de Causa Raiz

O aviso do vLLM descreve GPT-OSS Harmony em POST /v1/responses. A entrada inicial passava request.cache_salt a tokens_input; após uma ferramenta integrada ou MCP, a continuação usava tokens_input(token_ids) sem o salt. O helper só guarda o salt quando recebido. Assim, com cache automático de prefixo em ambiente compartilhado, a continuação usava o espaço sem salt. O aviso lista versões anteriores a 0.30.0, confirma o comportamento em 0.25.1 e diz que o limite inferior não está estabelecido. O resultado é um sinal de pertencimento ao cache via cached_tokens_per_turn, não divulgação direta de texto arbitrário do prompt. CWE-200 também aparece no aviso como impacto; CWE-524 é a única fraqueza principal aqui.[1], [3], [4]

Fluxo de Ataque Passo a Paso

Passo 1

Um serviço compartilhado atende aos pré-requisitos

O cenário exige versão afetada, GPT-OSS Harmony Responses, cache de prefixo e uma ferramenta; a vítima define cache_salt e chega à continuação.[1]

Passo 2

A primeira entrada do mecanismo recebe o salt

A chamada inicial de tokens_input inclui request.cache_salt e coloca o primeiro prefixo no espaço com salt do chamador.[1]

Passo 3

A continuação da ferramenta perde o salt

Após o resultado da ferramenta, a continuação chama tokens_input(token_ids) sem o salt original; o prefixo pode entrar no espaço compartilhado sem salt.[1]

Passo 4

Uma contagem de cache pode revelar pertencimento

Um tenant que reconstrua o prefixo após a ferramenta pode consultar cached_tokens_per_turn para inferir pertencimento, não recuperar texto arbitrário do prompt.[1]

Passo 5

O renderer mantém o salt em cada turno

A refatoração integrada mantém cache_salt na renderização Harmony e o passa a cada nova entrada do mecanismo; atualize para 0.30.0+.[1], [3], [7]

Código-Fonte: Vulnerável vs. Seguro

O aviso do vLLM descreve GPT-OSS Harmony em POST /v1/responses. A entrada inicial passava request.cache_salt a tokens_input; após uma ferramenta integrada ou MCP, a continuação usava tokens_input(token_ids) sem o salt. O helper só guarda o salt quando recebido. Assim, com cache automático de prefixo em ambiente compartilhado, a continuação usava o espaço sem salt. O aviso lista versões anteriores a 0.30.0, confirma o comportamento em 0.25.1 e diz que o limite inferior não está estabelecido. O resultado é um sinal de pertencimento ao cache via cached_tokens_per_turn, não divulgação direta de texto arbitrário do prompt. CWE-200 também aparece no aviso como impacto; CWE-524 é a única fraqueza principal aqui. Upstream excerpts, not a literal line-by-line diff.[1], [3], [4], [7]

Trecho de origem: renderer Harmony de Responses do vLLM (trechos de versões distintas)

IMPLEMENTAÇÃO VULNERÁVEL
# O caminho da solicitação inicial usava o salt, mas a continuação após a ferramenta não.
engine_input = tokens_input(token_ids, cache_salt=request.cache_salt)

# Após o resultado da ferramenta, a continuação reconstruía a entrada assim:
engine_input = tokens_input(token_ids)
PATCH SEGURO E ROBUSTO
# Preserve o salt da solicitação no contexto de renderização do 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,
)

# O renderizador fornece o salt sempre que cria a entrada do mecanismo.
engine_input = tokens_input(prompt["prompt_token_ids"], cache_salt=cache_salt)

Lista de Verificação de Segurança para Engenharia

Fontes