CVE-2026-105752
vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle
vLLM is an inference and serving engine for large language models. Prior to 0.30.0, Harmony tool continuations submitted through "POST /v1/responses" requests rebuild the next-turn engine input without preserving the cache_salt value, placing the continuation prefix in the global unsalted cache namespace even when the caller enabled salting. On deployments with prefix caching enabled, which is the default, an authenticated tenant who can reconstruct a victim's low-entropy post-tool history can submit the same continuation and use the cached_tokens_per_turn count to determine whether the prefix was previously processed, defeating the intended tenant isolation of salted prefix caching. This issue is fixed in version 0.30.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
3.1
vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle
vLLM is an inference and serving engine for large language models. Prior to 0.30.0, Harmony tool continuations submitted through "POST /v1/responses" requests rebuild the next-turn engine input without preserving the cache_salt value, placing the continuation prefix in the global unsalted cache namespace even when the caller enabled salting. On deployments with prefix caching enabled, which is the default, an authenticated tenant who can reconstruct a victim's low-entropy post-tool history can submit the same continuation and use the cached_tokens_per_turn count to determine whether the prefix was previously processed, defeating the intended tenant isolation of salted prefix caching. This issue is fixed in version 0.30.0.
- Record
CVE-2026-105752- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-200, CWE-524
- Updated
- 2026-11-02
EUVDEUVD-2026-92842
3.1
vLLM is an inference and serving engine for large language models. Prior to 0.30.0, Harmony tool continuations submitted through "POST /v1/responses" requests rebuild the next-turn engine input without preserving the cache_salt value, placing the continuation prefix in the global unsalted cache namespace even when the caller enabled salting. On deployments with prefix caching enabled, which is the default, an authenticated tenant who can reconstruct a victim's low-entropy post-tool history can submit the same continuation and use the cached_tokens_per_turn count to determine whether the prefix was previously processed, defeating the intended tenant isolation of salted prefix caching. This issue is fixed in version 0.30.0.
- Record
EUVD-2026-92842- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-935w-9g4m-p28p
3.1
vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle
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 drop (sink):
vllm/entrypoints/openai/responses/serving.py#L712-L713—token_ids = context.render_for_completion()thenengine_input = tokens_input(token_ids), with nocache_salt. - Correct turn-1 call for contrast:
vllm/entrypoints/openai/responses/serving.py#L755—tokens_input(prompt_token_ids, cache_salt=request.cache_salt). tokens_inputstores the salt only if passed:vllm/inputs/engine.py#L51-L66(if cache_salt is not None: inputs["cache_salt"] = cache_salt).- The engine request copies only the current input's salt:
vllm/v1/engine/input_processor.py#L380(cache_salt=decoder_inputs.get("cache_salt")→Nonefor the continuation). - Prefix-cache hashing keys on the salt only when present:
vllm/v1/core/kv_cache_utils.py#L560-L561([request.cache_salt] if (start_token_idx == 0 and request.cache_salt) else []). - The oracle the attacker reads:
vllm/entrypoints/openai/responses/serving.py#L909(cached_tokens_per_turn). - The documented control being defeated:…
- Record
GHSA-935w-9g4m-p28p- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-200, CWE-524
- Updated
- 2026-11-02
NVD
3.1
vLLM is an inference and serving engine for large language models. Prior to 0.30.0, Harmony tool continuations submitted through "POST /v1/responses" requests rebuild the next-turn engine input without preserving the cache_salt value, placing the continuation prefix in the global unsalted cache namespace even when the caller enabled salting. On deployments with prefix caching enabled, which is the default, an authenticated tenant who can reconstruct a victim's low-entropy post-tool history can submit the same continuation and use the cached_tokens_per_turn count to determine whether the prefix was previously processed, defeating the intended tenant isolation of salted prefix caching. This issue is fixed in version 0.30.0.
- Record
CVE-2026-105752- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-200, CWE-524
- Updated
- 2026-11-02
OSV
3.1
vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle
vLLM is an inference and serving engine for large language models. Prior to 0.30.0, Harmony tool continuations submitted through "POST /v1/responses" requests rebuild the next-turn engine input without preserving the cache_salt value, placing the continuation prefix in the global unsalted cache namespace even when the caller enabled salting. On deployments with prefix caching enabled, which is the default, an authenticated tenant who can reconstruct a victim's low-entropy post-tool history can submit the same continuation and use the cached_tokens_per_turn count to determine whether the prefix was previously processed, defeating the intended tenant isolation of salted prefix caching. This issue is fixed in version 0.30.0.
- Record
CVE-2026-105752- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-200, CWE-524
- Updated
- 2026-11-04
OSVGHSA-935w-9g4m-p28p
3.1
vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle
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 drop (sink):
vllm/entrypoints/openai/responses/serving.py#L712-L713—token_ids = context.render_for_completion()thenengine_input = tokens_input(token_ids), with nocache_salt. - Correct turn-1 call for contrast:
vllm/entrypoints/openai/responses/serving.py#L755—tokens_input(prompt_token_ids, cache_salt=request.cache_salt). tokens_inputstores the salt only if passed:vllm/inputs/engine.py#L51-L66(if cache_salt is not None: inputs["cache_salt"] = cache_salt).- The engine request copies only the current input's salt:
vllm/v1/engine/input_processor.py#L380(cache_salt=decoder_inputs.get("cache_salt")→Nonefor the continuation). - Prefix-cache hashing keys on the salt only when present:
vllm/v1/core/kv_cache_utils.py#L560-L561([request.cache_salt] if (start_token_idx == 0 and request.cache_salt) else []). - The oracle the attacker reads:
vllm/entrypoints/openai/responses/serving.py#L909(cached_tokens_per_turn). - The documented control being defeated:…
- Record
GHSA-935w-9g4m-p28p- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Weakness
- CWE-200, CWE-524
- Updated
- 2026-11-02
OSVPYSEC-2026-4308
3.1
vLLM: Harmony tool continuations drop `cache_salt` — restoring a cross-tenant prefix-cache membership oracle
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 drop (sink):
vllm/entrypoints/openai/responses/serving.py#L712-L713—token_ids = context.render_for_completion()thenengine_input = tokens_input(token_ids), with nocache_salt. - Correct turn-1 call for contrast:
vllm/entrypoints/openai/responses/serving.py#L755—tokens_input(prompt_token_ids, cache_salt=request.cache_salt). tokens_inputstores the salt only if passed:vllm/inputs/engine.py#L51-L66(if cache_salt is not None: inputs["cache_salt"] = cache_salt).- The engine request copies only the current input's salt:
vllm/v1/engine/input_processor.py#L380(cache_salt=decoder_inputs.get("cache_salt")→Nonefor the continuation). - Prefix-cache hashing keys on the salt only when present:
vllm/v1/core/kv_cache_utils.py#L560-L561([request.cache_salt] if (start_token_idx == 0 and request.cache_salt) else []). - The oracle the attacker reads:
vllm/entrypoints/openai/responses/serving.py#L909(cached_tokens_per_turn). - The documented control being defeated:…
- Record
PYSEC-2026-4308- CVSS 3.1
- 3.1 Low
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:N/I:L/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
vllmPyPI |
before 0.30.0 | 0.30.0 |
vllmPyPI |
before 0.30.0, plus listed versions 0.0.10.1.00.1.10.1.20.1.3 Show 45 moreShow less0.1.40.1.50.1.60.1.70.10.00.10.10.10.1.10.10.20.11.00.11.10.11.20.12.00.13.00.14.00.14.10.15.00.15.10.16.00.17.00.17.10.18.00.18.10.19.00.19.10.2.00.2.10.2.1.post10.2.20.2.30.2.40.2.50.2.60.2.70.20.00.20.10.20.20.21.00.22.00.22.10.23.00.24.00.25.00.25.10.26.00.27.0 |
0.30.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-105752 is a low vulnerability (CVSS 3.1) in Vllm, published October 5, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.22%, the 12th percentile. Fixed in vllm 0.30.0.
References
github.com/vllm-project/vllm/security/advisories/GHSA-935w-9g4m-p28p
github.com/vllm-project/vllm/pull/50195
github.com/vllm-project/vllm/pull/51818
github.com/vllm-project/vllm/commit/6a2a2bb02b563b83f946012959fd3927984d072a
github.com/vllm-project/vllm/releases/tag/v0.30.0
github.com/advisories/GHSA-935w-9g4m-p28p
Left out here: 47 versions and the rest of 3 source descriptions. The JSON record has them.