Baja

vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle

  • Publicada: 06.10.2026
  • Actualizado: 15.10.2026 18:17

Affected

  • Ecosystem / package: pip / vllm
  • Affected versions: vLLM ≤ 0.25.1 (confirmed on 0.25.1, commit 752a3a504485). The lower bound predates 0.25.1; maintainers can confirm how far back the tool-continuation re-submission has omitted the salt.

Summary

On the GPT-OSS "Harmony" path (POST /v1/responses), a request that uses a built-in or MCP tool runs as a multi-turn loop: after each tool call vLLM re-renders the full next-turn Harmony prompt and re-submits it to the engine. Turn 1 correctly carries request.cache_salt, but the tool-continuation re-submission rebuilds the engine input via tokens_input(token_ids) with no cache_salt. The continuation prefix is therefore cached in the global unsalted namespace even though the caller opted into salting. A second tenant who can guess the low-entropy post-tool history submits the reconstructed continuation (unsalted) and reads exact per-turn cached-token counts from the Responses usage — restoring the prompt-membership oracle that cache_salt is documented to prevent.

Silently dropping a preserved salt after the supported tool workflow is enabled is a broken isolation control: the caller enabled salting and every turn should stay isolated, but continuation turns leak into the shared cache.

This is distinct from GHSA-4qjh-9fv9-r85r (CVE-2025-46570): that advisory is the prefix-cache membership oracle for which cache_salt is the documented mitigation, and its PR-17045 fix does not close this site — the Harmony tool continuation silently drops the preserved salt, caching in the unsalted namespace and leaking exact cached_tokens_per_turn counts from a different sink (the Responses serving continuation, not general TTFT timing).

Affected code

Links pinned to the confirmed commit 752a3a504485 (v0.25.1):

The tool-continuation re-submission rebuilds the engine input with no cache_salt:

python
# vllm/entrypoints/openai/responses/serving.py Lines 711-715
            if isinstance(context, HarmonyContext):
                token_ids = context.render_for_completion()
                engine_input = tokens_input(token_ids)

                sampling_params.max_tokens = max_model_len - len(token_ids)

Contrast with the correct turn-1 call, which does preserve the caller's salt:

python
# vllm/entrypoints/openai/responses/serving.py Lines 754-755
        prompt_token_ids = render_for_completion(messages)
        engine_input = tokens_input(prompt_token_ids, cache_salt=request.cache_salt)

tokens_input stores the salt on the engine input only when it is passed, so the continuation input carries none and lands in the unsalted namespace:

python
# vllm/inputs/engine.py Lines 51-66
def tokens_input(
    prompt_token_ids: list[int],
    *,
    prompt: str | None = None,
    cache_salt: str | None = None,
) -> TokensInput:
    """
    Construct [`TokensInput`][vllm.inputs.engine.TokensInput]
    from optional values.
    """
    inputs = TokensInput(type="token", prompt_token_ids=prompt_token_ids)

    if prompt is not None:
        inputs["prompt"] = prompt
    if cache_salt is not None:
        inputs["cache_salt"] = cache_salt

Impact

An authenticated tenant of a shared deployment can recover whether a guessed post-tool prompt or history was processed by another tenant, with exact cached-token counts rather than noisy latency — the exact prompt-membership oracle cache_salt is documented to prevent. It defeats the multi-user prefix-cache isolation guarantee for salted Harmony tool sessions.

Preconditions: a GPT-OSS Harmony model on /v1/responses; prefix caching enabled (default); an operator-enabled built-in or MCP tool server; the victim sets cache_salt and triggers at least one tool continuation; and the attacker can reconstruct the post-tool history closely enough to match the token prefix. The AC:H metric reflects that guessable-history precondition.

Suggested Fix

Propagate request.cache_salt into every Harmony (and Parsable) tool-continuation re-submission — at the continuation call site call tokens_input(token_ids, cache_salt=request.cache_salt), mirroring the correct turn-1 call. Carry the salt on the HarmonyContext (thread the originating request into the context) so no continuation path can omit it:

diff
# vllm/entrypoints/openai/responses/serving.py
             if isinstance(context, HarmonyContext):
                 token_ids = context.render_for_completion()
-                engine_input = tokens_input(token_ids)
+                engine_input = tokens_input(
+                    token_ids,
+                    cache_salt=(
+                        context.request.cache_salt
+                        if context.request is not None
+                        else None
+                    ),
+                )

with HarmonyContext.__init__ gaining a request: ResponsesRequest | None = None parameter (stored as self.request) that _create_responses passes when constructing the context. The continuation prefix is then cached in the victim's salted namespace, mirroring turn 1.

Suggested regression test: assert cached_tokens_per_turn == 0 for a different-salt probe against a salted victim continuation (the four-way control from the proof of concept).

Credit

Reported by: Patch the Planet (Trail of Bits + OpenAI collaboration)

This vulnerability was discovered using GPT-5.5-Cyber as part of the Patch the Planet security initiative.


Proposed fix: a fix for this issue is proposed in a public pull request: https://github.com/vllm-project/vllm/pull/51818

Software afectado

Haz clic en una tecnología para ver todas sus vulnerabilidades.

PlataformaPaqueteVersiones vulnerablesCorregida en
Python (PyPI) vllm < 0.30.0 0.30.0

Referencias

Puntuación CVSS 3.1/10
Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N
Debilidad (CWE)
CWE-200, CWE-524
Plataforma
Python (PyPI)
Paquete
vllm
Publicada
06.10.2026
Actualizado
15.10.2026 18:17

Fuentes y licencias

OSV / GitHub Advisory Database - PYSEC-2026-4308 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-935w-9g4m-p28p - CC BY 4.0

Historial de vulnerabilidades: vllm

Todas las vulnerabilidades publicadas de este paquete (Python (PyPI)), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.

Todas (94) en el archivo
Entradas en total
94
Primera → última
09.2024 10.2026
Sin corrección
5
Explotada en ataques
0

Distribución por gravedad

  • Crítica 9
  • Alta 23
  • Media 47
  • Baja 4
  • Sin evaluar 11

Divulgaciones por año

  1. 2024: 2
  2. 2025: 30
  3. 2026: 62
Gravedad:
  1. vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle esta entrada
    Baja · 3.1 CVE-2026-105752 < 0.30.0 0.30.0
  2. Alta · 7.5 CVE-2026-54234 >= 0.17.1, < 0.24.0 0.24.0
  3. Alta CVE-2026-55514 >= 0.12.0, < 0.24.0 0.24.0
  4. Crítica · 9.1 CVE-2026-48746 >= 0.3.0, < 0.22.0 0.22.0
  5. Crítica · 9.8 CVE-2026-22778 >= 0.8.3, < 0.14.1 0.14.1
  6. Alta · 8.8 CVE-2026-22807 >= 0.10.1, < 0.14.0 0.14.0
  7. Alta · 8.8 CVE-2026-56340 >= 0.10.2, < 0.13.0 0.13.0
  8. Alta · 6.5 CVE-2025-62372 >= 0.5.5, < 0.11.1 0.11.1
  9. Alta · 8.8 CVE-2025-62164 >= 0.10.2, < 0.11.1 0.11.1
  10. Alta · 7.5 CVE-2025-59425 < 0.11.0 0.11.0
Mostrar más (13) Mostrando 20 de 33

Identifica las vulnerabilidades de tu aplicación

Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.