Cloudflare Discloses a Workers AI Cross-Tenant Leak: 155 GLM-5.3 Responses Contained Other Customers' Request Data, Caused by a KV Cache Pool Smaller Than the Context Window Plus a Bug in SGLang's Rejection Path

In a coordinated disclosure with the open-source inference engine SGLang on October 26, Cloudflare said that between August 27 and September 9, 155 responses from the GLM-5.3 model on Workers AI (@cf/zai-org/glm-5.3) contained content from other customers' earlier requests, all in reply to prompts longer than 681,280 tokens, with no evidence of deliberate exploitation. There were two layers to the cause. Cloudflare launched the model with a 1,048,576-token context window, but the KV cache pool on its prefill GPUs held only 681,280 tokens; the team knew about the gap before launch but only checked HTTP status codes. And in disaggregated prefill/decode mode, SGLang replaced requests that didn't fit with a one-token placeholder and handed them off as usual, so the decode node read stale cache pages still holding other users' data while the client received HTTP 200. Security researcher Gadi Evron reported the issue through HackerOne on September 8; Cloudflare reproduced it the next morning, took the model offline within 40 minutes and restored it with fixes the same day. SGLang has fixed the bug in v0.5.20 through v0.5.22, and Cloudflare advises operators running disaggregated deployments to upgrade to v0.5.22 or later.

What happened

Cloudflare published an incident report on October 26 as a coordinated disclosure with the open-source inference engine SGLang. Between August 27 and September 9, a small number of customers using the GLM-5.3 model on Workers AI (@cf/zai-org/glm-5.3) received responses containing content from other customers' requests made to the same model shortly before. In total 155 responses were affected, all replies to prompts longer than 681,280 tokens. After excluding Cloudflare's own testing and the researcher's, the requests looked like ordinary long-context use in timing and volume, with no evidence of deliberate exploitation. No other Workers AI model was affected.

Security researcher Gadi Evron of Knostic reported the issue through HackerOne on September 8. The next morning Cloudflare reproduced it with two independent accounts within 25 minutes, took the model offline within 40 minutes of declaring an incident (requests began returning HTTP 400), and restored service the same day with a corrected configuration and a patched engine.

Two problems stacked together

The first was configuration. GLM-5.3 launched with a 1,048,576-token context window, but the KV cache pool on the prefill GPUs only had room for 681,280 tokens. SGLang sizes the pool at startup from the GPU memory left after loading weights, and that is a separate value from the advertised context length; nothing forces them to agree. Cloudflare knew about the gap before launch, but its long-context tests only checked HTTP status codes and performance, both of which looked fine, so it assumed the engine handled the difference gracefully and never checked whether the output was coherent.

The second was a bug in SGLang's disaggregated prefill/decode mode. A request that didn't fit was internally marked as rejected and swapped for a one-token placeholder so it could drain through the normal batch machinery. On a single node the client got an error. But in disaggregated mode, the admission checks only asked whether a request had finished, not whether it had been rejected, so prefill computed the cache for one token and told the decode node the transfer was complete. Decode had reserved pages for the full prompt length; only the first page was written by this request, and the rest still held earlier users' prompts and generations. The client got HTTP 200, prompt_tokens matched the long prompt and the reply was coherent; it just arrived faster than a full prefill should and carried someone else's data. A user had already reported a similar problem to SGLang as issue #30233 on July 6.

Fixes, and advice for other operators

Cloudflare reconfigured the model so the prefill cache pool holds about 2.04 million tokens, roughly twice the context length, and patched the engine so rejected requests exit with their original error before any allocation or transfer. SGLang's fix shipped in v0.5.20, with v0.5.21 and v0.5.22 adding per-transfer checksums, preserved abort acknowledgements and deferred KV release on by default.

For teams running SGLang in disaggregated mode, Cloudflare's advice is specific: after every change to weights, quantization, parallelism or memory fraction, check each node's KV pool size against the context length in the startup log, and lower the context length if the pool is smaller; upgrade to v0.5.22 or later; and turn on deferred release and cache checksums. It also concedes that configuration checks only reduce the ways things can go wrong. The durable fix is for the engine to confirm, before reading each cache page, that the page belongs to the current request.

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