Cloudflare 披露 Workers AI 串号事故:GLM-5.3 有 155 个回复混入别人的请求内容,根因是 KV 缓存池比上下文窗口小、加上 SGLang 拒绝路径的缺陷

Cloudflare 10 月 26 日与开源推理引擎 SGLang 协同披露:8 月 27 日至 9 月 9 日,Workers AI 上的 GLM-5.3 模型(@cf/zai-org/glm-5.3)有 155 个回复混入了其他客户此前请求的内容,全部发生在提示超过 681,280 个 token 的长请求上,未发现蓄意利用。起因有两层:Cloudflare 以 1,048,576 token 的上下文窗口上线该模型,但预填充 GPU 上的 KV 缓存池只能容纳 681,280 token,团队上线前知道这一差距,却只检查了 HTTP 状态码;SGLang 在预填充与解码分离部署下,把放不下的请求替换成 1 个 token 的占位并照常移交,解码节点读取了仍留有别人数据的旧缓存页,客户端收到的是 HTTP 200。安全研究员 Gadi Evron 9 月 8 日经 HackerOne 报告,Cloudflare 次日复现后 40 分钟内下线模型,当天修复恢复。SGLang 已在 v0.5.20 至 v0.5.22 中修复,Cloudflare 建议分离部署的运营方升级到 v0.5.22 或以上。

发生了什么

Cloudflare 10 月 26 日发布事故报告,与开源推理引擎 SGLang 同步做协调披露:8 月 27 日至 9 月 9 日,Workers AI 上的 GLM-5.3 模型(@cf/zai-org/glm-5.3)有少数客户收到的回复里,混入了其他客户不久前对同一模型发出的请求内容,共 155 个回复,全部是对超过 681,280 个 token 的长提示的回复。排除 Cloudflare 自己和研究员的测试后,相关请求在时间和数量上都像正常的长上下文使用,没有发现蓄意利用。其他 Workers AI 模型不受影响。

问题由 Knostic 的安全研究员 Gadi Evron 9 月 8 日通过 HackerOne 报告。Cloudflare 次日早上用两个独立账号在 25 分钟内复现,宣布事故后 40 分钟内把模型下线(请求改为返回 HTTP 400),当天部署修正配置和打过补丁的引擎后恢复服务。

两个问题叠在一起

第一层是配置:GLM-5.3 以 1,048,576 token 的上下文窗口上线,但预填充 GPU 上的 KV 缓存池只装得下 681,280 token。SGLang 在启动时按加载权重后剩余的显存决定缓存池大小,它与对外宣称的上下文长度是两个互不约束的配置。Cloudflare 上线前就知道这个差距,但长上下文测试只看了 HTTP 状态码和性能,都是成功,于是以为引擎会妥善处理,没有检查输出内容是否连贯。

第二层是 SGLang 在预填充与解码分离部署下的缺陷。放不下的请求在内部被标记为拒绝,并被替换成 1 个 token 的占位,以便走完正常的批处理流程。单机部署时客户端会收到错误;但分离部署的准入检查只判断请求「是否结束」,不判断「是否被拒绝」,于是预填充只算了 1 个 token 的缓存就通知解码节点「传输完成」。解码节点按原长度预留了缓存页,其中只有第一页是这个请求写的,其余页仍留着之前其他用户的提示和生成内容。客户端收到 HTTP 200,prompt_tokens 与长提示对得上,回复也连贯,只是比正常预填充快,且夹带了别人的数据。同类问题 7 月 6 日已有用户以 issue #30233 报告给 SGLang。

修复与给其他运营方的建议

Cloudflare 调整配置,让预填充缓存池容纳约 204 万 token,约为上下文长度的两倍;同时给引擎打补丁,让被拒绝的请求在任何分配和传输之前就以原始错误退出。SGLang 的修复在 v0.5.20 发布,v0.5.21、v0.5.22 补上每次传输的校验和、中止确认保留和默认开启的延迟释放。

对自己用 SGLang 分离部署的团队,Cloudflare 的建议很具体:每次改动权重、量化、并行方式或显存比例后,从启动日志核对每个节点的 KV 缓存池是否不小于上下文长度,小了就把上下文长度调低;升级到 v0.5.22 或以上;开启延迟释放和缓存校验。它也承认,配置检查只能减少出错路径,长期办法是让引擎在读取每一页缓存前确认这页是否属于当前请求。

via: Cloudflare Blog:Cross-request KV cache exposure in the GLM-5.3 Workers AI model, and our remediation with SGLang