在 vLLM 0.30.0 之前的另一处问题被编号为 CVE-2026-105752。它描述的场景非常具体:当请求通过 POST /v1/responses 提交一个 Harmony 工具续接(tool continuation)时,服务端要重建下一轮的引擎输入,却在重建过程里丢掉了 cache_salt 这个值。结果是,哪怕调用方本来开了缓存加盐,这条续接的前缀还是被塞进了全局的无盐缓存命名空间。在默认开启前缀缓存的部署上,一个已认证租户只要能重构出受害者的前缀,就能撞上这段缓存。

cache_salt 到底是个什么东西,为什么丢了就危险?

前缀缓存是 vLLM 这类引擎省算力的核心手段:把一个请求里开头那段公共前缀的 KV 结果存下来,下一个请求前缀一样就直接复用。问题是缓存键是按前缀内容算的,如果大家都用同一段系统提示,那缓存键就一样——A 请求存进去的前缀表示,B 请求能直接读出来。cache_salt 就是给这个缓存键撒的一把盐:不同租户用不同盐,键就分开,互相读不到。它本质是个多租户隔离机制,靠的是「键里掺了只有你知道的随机串」。

续接为什么会把这把盐弄丢?

罪魁在「重建」。Agent 多轮对话里,工具调用不是一次发完的,模型调一次工具、拿到结果、再接着生成,这中间服务端要把上一轮状态重新拼回引擎输入。拼的过程本来是个机械重组,开发者容易默认「前缀没变,缓存键自然沿用旧的」。但恰恰在这条 Harmony 续接路径上,重建逻辑没有把 cache_salt 这个元字段一起带过来,于是新的引擎输入落到了不加盐的默认命名空间里。一个本该隔离的会话前缀,就此和其他租户的前缀排在了同一个无盐池子里。

这条链能造成多大的实际后果?

它不是远程代码执行,更像一条横向越界的信息泄漏:已认证的租户 A,只要能猜到或重构出租户 B 的请求前缀(比如一段公开的系统提示加固定的工具格式),就能命中 B 被无盐缓存的那一段,拿到它此前的 KV 缓存甚至触发缓存命中侧的行为差异。对多租户 API 厂商,这是把「逻辑隔离」从默认值里悄悄撤掉。修法也直接:0.30.0 要求续接重建时必须原样保留 cache_salt。这件事真正的教训是——缓存优化是性能生命线,但每一处「为了复用而做的键拼接」,都得单独审一遍隔离语义。

去论坛讨论

前往 silicon-agi.com 论坛 参与讨论