---
title: "Cloudflare expuso datos entre clientes en GLM-5.3 de Workers AI: un bug de SGLang y una mala configuración"
url: https://hernandez.systems/es/articulos/cloudflare-expuso-datos-entre-clientes-en-glm-53-de-workers-ai
lang: es
type: NewsArticle
section: Infraestructura
published: "2026-10-30T03:28:18+00:00"
modified: "2026-10-30T06:55:06+00:00"
publisher: Osky Networks
image: https://oskydj.sfo3.cdn.digitaloceanspaces.com/calamardo/news_item/2026-10-30/e10-35b38df8.jpg
alternate_en: https://hernandez.systems/en/articles/cloudflare-exposed-data-between-customers-on-workers-ais-glm-5-3-an-sglang-bug-and-a
---

# Cloudflare expuso datos entre clientes en GLM-5.3 de Workers AI: un bug de SGLang y una mala configuración

> Cloudflare publicó el 26 de octubre un reporte de incidente que debería leer cualquiera que sirva modelos de lenguaje a varios clientes con la misma infraestructura. Entre el 27 de agosto y el 9 de septiembre de 2026, el modelo GLM-5.3 de Workers AI (@cf/zai-org/glm-5.3) devolvió a algunos clientes respuestas que contenían datos de peticiones de otros clientes hechas poco antes al mismo modelo. Según Cloudflare, fueron 155 respuestas afectadas, todas a prompts de más de 681,280 tokens. La causa fue la combinación de una mala configuración propia y un bug en SGLang, el motor de inferencia de código abierto que usan. El reporte salió como divulgación coordinada con el equipo de SGLang, que publicó su propio análisis técnico el mismo día.

Cloudflare publicó el 26 de octubre un reporte de incidente que debería leer cualquiera que sirva modelos de lenguaje a varios clientes con la misma infraestructura. Entre el 27 de agosto y el 9 de septiembre de 2026, el modelo GLM-5.3 de Workers AI (`@cf/zai-org/glm-5.3`) devolvió a algunos clientes respuestas que contenían datos de peticiones de otros clientes hechas poco antes al mismo modelo. Según Cloudflare, fueron 155 respuestas afectadas, todas a prompts de más de 681,280 tokens. La causa fue la combinación de una mala configuración propia y un bug en SGLang, el motor de inferencia de código abierto que usan. El reporte salió como divulgación coordinada con el equipo de SGLang, que publicó su propio análisis técnico el mismo día.

## Qué pasó, en corto

El 8 de septiembre, el investigador Gadi Evron, de Knostic, reportó por el programa de HackerOne de Cloudflare que los prompts muy largos enviados a GLM-5.3 a veces regresaban texto de sesiones de otros usuarios. Cloudflare reprodujo el problema a la mañana siguiente, declaró un incidente de seguridad, puso el modelo en privado (las peticiones empezaron a devolver HTTP 400) y lo restauró esa misma tarde con la configuración corregida y un parche al motor.

Cloudflare dice que, excluyendo sus propias pruebas y las del investigador, las peticiones afectadas coinciden en tiempo y volumen con un uso normal de contexto largo, y que no encontró evidencia de explotación deliberada. También asegura que ningún otro modelo de Workers AI estuvo expuesto, porque en el resto de sus despliegues el pool de caché es más grande que la ventana de contexto.

## Dos errores que se encontraron en el peor lugar

Workers AI sirve GLM-5.3 con SGLang en modo **desagregado**: un grupo de GPU hace el *prefill* (procesa el prompt y genera la caché KV, las claves y valores de atención que el modelo necesita para seguir generando) y otro grupo hace el *decode* (genera la respuesta). La caché viaja de un grupo a otro por RDMA, con Mooncake. Esa caché vive en un pool compartido de páginas de tamaño fijo que **no se ponen en cero entre peticiones**: la siguiente petición que recibe una página simplemente la sobrescribe. Cloudflare explica que esto es común entre motores de inferencia porque es necesario para el rendimiento, pero deja toda la responsabilidad de saber de quién es cada página en el motor.

**Error uno: la configuración.** Cloudflare anunció GLM-5.3 con una ventana de contexto de 1,048,576 tokens, pero el pool de caché KV en sus GPU de prefill solo tenía espacio para 681,280. SGLang calcula ese pool al arrancar con la memoria que sobra después de cargar los pesos; la ventana de contexto es un valor aparte y nada obliga a que coincidan. Cloudflare reconoce que conocía la diferencia antes del lanzamiento, pero supuso que el motor rechazaría con un error lo que no cupiera. Sus pruebas de contexto largo solo revisaban códigos HTTP y rendimiento, no si la respuesta tenía sentido, y todas regresaban 200.

**Error dos: el bug de SGLang.** Cuando un prompt no cabía en el pool, el planificador lo marcaba como rechazado y lo reemplazaba por un marcador de un solo token, para que la petición saliera por el flujo normal sin reservar memoria. En un solo nodo eso funcionaba: el cliente recibía un error. Pero en modo desagregado, las colas de admisión revisaban si la petición estaba *terminada*, no si estaba *rechazada*, y una petición rechazada seguía reportándose como viva. El resultado, según la secuencia que describe Cloudflare:

- El decode reservaba páginas para el prompt completo (8 en su ejemplo).
- El prefill procesaba solo el token de relleno y mandaba una página.
- El decode recibía "transferencia completa" y generaba la respuesta leyendo las 8 páginas, aunque 7 seguían con lo que dejaron peticiones anteriores: prompts y generaciones parciales de otros usuarios.
- El cliente recibía HTTP 200 en lugar de 400, con una respuesta coherente que llegaba más rápido de lo normal y con contenido ajeno.

![Diagrama del bug: la GPU de prefill rechaza el prompt de más de 681,280 tokens, envía una sola página y reporta transferencia completa; la GPU de decode lee las 8 páginas reservadas, siete con restos de peticiones de otros usuarios, y responde HTTP 200 con contenido ajeno](https://oskydj.sfo3.cdn.digitaloceanspaces.com/calamardo/news_item/2026-10-30/e10-diagrama-48f65e96.png)

Cloudflare señala que otro usuario ya había reportado este bug en SGLang como el issue #30233, el 6 de julio de 2026, y que lo vieron hasta investigar el incidente.

## Cómo lo corrigieron

Cloudflare atacó los dos frentes. Primero ajustó la configuración de GLM-5.3 a la de GLM-5.2, lo que liberó memoria suficiente para que el pool de prefill tenga unos 2.04 millones de tokens, aproximadamente el doble de la ventana de contexto. Así, cualquier prompt válido cabe y nunca llega al camino de rechazo.

Como depender del tamaño del pool es frágil (cualquier cambio de cuantización, paralelismo tensorial o versión del modelo lo mueve), también parchó el motor para que una petición rechazada se retire en la cola de admisión, con su error original, antes de cualquier reserva o transferencia. Lo propuso upstream como el PR #38704. Los mantenedores de SGLang terminaron integrando dos cambios: #36988, que retira las peticiones abortadas antes de que su resultado llegue al decode, y #38935, que las rechaza desde la admisión siguiendo el enfoque de Cloudflare.

## La parte que va más allá de Cloudflare

Lo más útil del reporte, en mi lectura, es que este bug pertenece a una familia más grande. Tanto Cloudflare como el equipo de SGLang describen otra condición de carrera en despliegues desagregados: si una petición se aborta mientras el prefill todavía escribe su caché por RDMA, esas escrituras ya lanzadas no se pueden cancelar. Si el decode libera las páginas de inmediato y se las asigna a otra petición, las escrituras tardías caen en la caché de esa otra petición. SGLang dice que, dentro de los despliegues desagregados, las configuraciones por defecto estuvieron expuestas a esta carrera desde la línea v0.4.x (principios de 2025) hasta v0.5.21, o v0.5.22 si se usa MORI como backend de transferencia. Agrega que el riesgo crece con el contexto largo, que no deja errores ni líneas en el log y que un operador no tiene forma confiable de saber si ya le pasó.

La solución principal es la **liberación diferida**: el decode retiene las páginas de una petición abortada hasta que cada rango de prefill confirma que ya no tiene escrituras en vuelo, o hasta que vence un tiempo límite. Según las pruebas de SGLang en 2×H100, el impacto en throughput fue estadísticamente indistinguible de no tenerla, con diferencias dentro de ±2%.

| Versión de SGLang | Qué trae para esta familia de bugs |
|---|---|
| v0.5.20 | #36988 (corrige la exposición del incidente) y tope opcional al tamaño de los lotes de Mooncake |
| v0.5.21 (2 de oct.) | #38935 (rechazo desde la admisión), liberación diferida activa por defecto para Mooncake y NIXL, checksum opcional de la caché transferida |
| v0.5.22 (19 de oct.) | Soporte para MORI, confirmaciones etiquetadas por petición, envíos fallidos de Mooncake que ya no se reportan como drenados, métricas de liberación diferida |

## Qué deberías hacer

**Si usas Workers AI:** según Cloudflare, el problema se limitó a GLM-5.3, solo afectó a prompts de más de 681,280 tokens y quedó corregido el 9 de septiembre. Ni el reporte de Cloudflare ni el de SGLang dicen si avisaron directamente a los clientes afectados.

**Si operas SGLang en modo desagregado prefill/decode,** Cloudflare recomienda:

1. Comparar el tamaño del pool KV (aparece en el log de arranque) con la ventana de contexto en cada nodo, después de cualquier cambio de pesos, cuantización, paralelismo o fracción de memoria. Si el pool es menor, baja la ventana. No asumas que el motor rechazará lo que no cabe.
2. Actualizar a SGLang v0.5.22 o posterior, o integrar #36988 y #38935.
3. Correr con liberación diferida en ambos roles (es el comportamiento por defecto desde v0.5.21) y limitar el tamaño de los lotes de Mooncake.
4. Activar la detección de corrupción donde el modelo la soporte, con `--disaggregation-enable-kv-checksum` y `--kv-canary`. Ojo: todavía no cubren todas las arquitecturas; Cloudflare dice que trabaja con SGLang para extenderlas a más, incluidas GLM 5.3, GLM 5.3 Flash y DeepSeek V4. Revisa tus logs para confirmar que las peticiones sí se están verificando.
5. Configurar el proxy o balanceador para que deje avanzar las peticiones hasta el primer token y no genere abortos innecesarios a media transferencia.

SGLang agrega que, después de actualizar, conviene vigilar la métrica `sglang:decode_deferred_kv_release_total{outcome}`: en un despliegue sano casi todas las retenciones deben terminar como `drained`, no por tiempo límite. Si sirves en un solo nodo, sin transferencia de caché entre motores, esta carrera en particular no te aplica.

## Mi lectura

Lo incómodo de este caso es que nada tronó. No hubo errores 500 ni alertas, y la respuesta era coherente. La lección que el propio Cloudflare admite es que probar un sistema de IA solo con códigos de estado y latencia no basta: hay que validar el contenido de la salida, por ejemplo con marcadores de canario como los que ellos usaron para confirmar la corrección. Para quien monta su propia infraestructura de inferencia multiinquilino, la regla sale casi sola: el aislamiento entre clientes no se puede delegar a que "el motor seguro lo maneja". Hay que medirlo.

A largo plazo, Cloudflare dice que trabaja con SGLang en etiquetas por página que se verifiquen en cada lectura (su prototipo costó menos de 1% de rendimiento, pero lo desactivaron por problemas de confiabilidad) y en verificación formal del protocolo de transferencia por RDMA. Falta ver cuánto de eso llega a producción.

## Fuentes

- [Cloudflare: Cross-request KV cache exposure in the GLM-5.3 Workers AI model, and our remediation with SGLang](https://blog.cloudflare.com/kv-cache-exposure-remediation/)
- [LMSYS / SGLang: SGLang security update: improving request isolation](https://www.lmsys.org/blog/2026-10-26-cf-security)
- [SGLang v0.5.22 en GitHub](https://github.com/sgl-project/sglang/releases/tag/v0.5.22)
- [Cloudflare Status: Workers AI increased errors (9 de septiembre de 2026)](https://www.cloudflarestatus.com/incidents/jsvvrtk5hvym)
