| عنوان | LMCache 729ff73 Cache poisoning |
|---|
| الوصف | ```text
LMCache vLLM multimodal cache key generation hash collision cache poisoning
```
## Vulnerability Type
```text
Cache poisoning caused by insufficient hash entropy / hash collision in multimodal cache key material.
```
Possible CWE candidates:
```text
CWE-328: Use of Weak Hash
CWE-327: Use of a Broken or Risky Cryptographic Algorithm
CWE-200: Exposure of Sensitive Information to an Unauthorized Actor
CWE-345: Insufficient Verification of Data Authenticity
```
Recommended primary CWE:
```text
CWE-328: Use of Weak Hash
```
## Severity
```text
CVSS 3.1: 7.4 High
Vector: AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:H/A:N
```
Rationale:
```text
The vulnerability is network-reachable in deployments accepting multimodal requests. It requires no privileges and no user interaction. Attack complexity is low because the vulnerable hash space is only 16 bits. The main impact is integrity: LMCache can return KV cache entries computed from a different image, causing the model to answer using incorrect visual context. Confidentiality impact is low because cross-user private image context may influence another user's output through the wrong KV cache. Availability impact is none or low because the service remains operational.
```
## Short Description
```text
LMCache contains a cache poisoning vulnerability in its vLLM multimodal integration. The function hex_hash_to_int16() truncates multimodal image identifiers to 16 bits before those values are used in token IDs that participate in cache key computation. Distinct images can therefore collide and cause LMCache to return KV cache entries generated for a different image, leading to incorrect model output and possible cross-user context leakage.
```
## Technical Description
```text
LMCache's multimodal caching mechanism converts multimodal identifiers into integer token replacements through hex_hash_to_int16() in lmcache/integration/vllm/utils.py.
For hexadecimal input, the function parses the value and applies a 16-bit mask:
int(hex_part, 16) & 0xFFFF
For non-hexadecimal input, including OpenAI-style identifiers such as chatcmpl-xxx-image-N, the function computes SHA-256 but only keeps the first two bytes:
hashlib.sha256(...).digest()[:2]
Both branches reduce high-entropy identifiers to a 16-bit space containing only 65,536 possible values. The resulting value is used by apply_mm_hashes_to_token_ids() to overwrite token IDs at multimodal placeholder positions. Those modified token IDs feed into cache key / chunk hash computation.
When two different images collide in this 16-bit value and the relevant prompt/token structure matches, LMCache can treat the requests as cache-equivalent and return a KV cache entry computed for the wrong image.
```
## Attack Scenario
```text
1. A deployment accepts multimodal requests using LMCache with vLLM integration.
2. An attacker sends requests with attacker-controlled or attacker-influenced image identifiers.
3. The attacker searches for an identifier whose 16-bit multimodal hash collides with another image identifier.
4. LMCache replaces multimodal placeholder token IDs with the same 16-bit value for two distinct images.
5. Cache key computation sees equivalent modified token IDs.
6. LMCache returns a cached KV entry computed for a different image.
7. The model generates output using the wrong visual context.
```
## Impact
```text
Integrity impact is high because the model may produce responses based on an image different from the one supplied by the user.
Confidentiality impact is low to medium because a user's output may be influenced by KV cache state computed from another user's private image.
Availability impact is low or none because exploitation does not require crashing the service.
The issue is practical because a 16-bit hash space has only 65,536 possible values. Birthday-paradox collisions are expected after roughly 300 distinct images, and brute-force collision search is trivial.
```
## Proof of Concept
```python
import hashlib
import string
import uuid
def hex_hash_to_int16(s):
s = "" if s is None else str(s)
s_stripped = s.strip()
hex_part = s_stripped[2:] if s_stripped.lower().startswith("0x") else s_stripped
if hex_part and all(c in string.hexdigits for c in hex_part):
try:
return int(hex_part, 16) & 0xFFFF
except ValueError:
pass
digest = hashlib.sha256(s_stripped.encode("utf-8")).digest()
return int.from_bytes(digest[:2], byteorder="big", signed=False)
seen = {}
for i in range(100_000):
ident = f"chatcmpl-{uuid.uuid4().hex}-image-{i}"
h = hex_hash_to_int16(ident)
if h in seen:
print(f"COLLISION at input #{i}:")
print(f" A: {seen[h]}")
print(f" B: {ident}")
print(f" hash: {h:#06x}")
break
seen[h] = ident
```
Expected result:
```text
The script finds a collision quickly, often after only a few hundred generated identifiers.
```
Empirical results from the disclosure draft:
```text
Average inputs to first collision, OpenAI-style IDs: 258
Average inputs to first collision, hex-style IDs: 265
Theoretical birthday-paradox threshold: about 321
Time to first collision: under 1 ms in the standalone test
Approximate collisions per 1000 images: 9
```
## Suggested Remediation
```text
Increase the multimodal hash value from 16 bits to at least 64 bits. token_ids already uses torch.long / int64, so this should not require a dtype change.
For hexadecimal input:
int(hex_part, 16) & 0xFFFFFFFFFFFFFFFF
For SHA-256 input:
int.from_bytes(digest[:8], byteorder="big", signed=False)
The function should be renamed from hex_hash_to_int16() to a name reflecting the wider output, such as hex_hash_to_int64(). Tests should verify that multimodal identifiers preserve enough entropy and that collisions are not expected in practical workloads.
```
## References
```text
Project repository: https://github.com/LMCache/LMCache
Security policy: https://github.com/LMCache/LMCache/blob/dev/SECURITY.md
Affected source path: lmcache/integration/vllm/utils.py
``` |
|---|
| المصدر | ⚠️ https://github.com/LMCache/LMCache/issues/3301 |
|---|
| المستخدم | Dem00 (UID 84913) |
|---|
| ارسال | 16/05/2026 06:38 PM (19 أيام منذ) |
|---|
| الاعتدال | 04/06/2026 07:34 AM (19 days later) |
|---|
| الحالة | تمت الموافقة |
|---|
| إدخال VulDB | 368261 [LMCache حتى 0.4.6 KV Cache utils.py hex_hash_to_int16 تشفير ضعيف] |
|---|
| النقاط | 20 |
|---|