
End-to-end reproduction and cross-layer detection of CVE-2026-53576, the unauthenticated RCE in Kestra - taken past the base PoC to show how a common Docker-socket misconfiguration turns container-root into full host compromise.
Kestra, una plataforma de orquestación de flujos de trabajo de código abierto, distribuyó un filtro de autenticación que decidía si una solicitud necesitaba credenciales comprobando si la URL terminaba con /configs - una comprobación destinada a exponer un único endpoint público inofensivo.
Debido a que la comprobación solo miraba el final de la cadena, cualquier solicitud cuya URL terminara de esa forma omitía por completo la autenticación, incluidos los endpoints que crean y ejecutan código arbitrario. El resultado: cualquiera que pueda alcanzar una instancia vulnerable de Kestra a través de la red puede ejecutar comandos como root sin credenciales, sin phishing, sin adivinar contraseñas y sin necesidad de ningún paso de escalada de privilegios.
En este ejercicio, esa única brecha se llevó de principio a fin contra una instancia de laboratorio autoalojada:
Cada etapa se capturó contra telemetría defensiva (IDS de red, seguridad en tiempo de ejecución del host, auditoría de Linux y registros del sistema).
Impacto empresarial si no se parchea: compromiso total del host que ejecuta Kestra, no solo de la aplicación, y por extensión de cualquier otra cosa alcanzable desde ese host.
Solución: actualizar a Kestra 1.0.45 / 1.3.21 o posterior (el parche por sí solo cierra la vulnerabilidad principal; las etapas de escalada y persistencia requieren una corrección separada e independiente: no montar el socket de Docker en contenedores de aplicaciones, véase la Sección 8).
Este informe documenta CVE-2026-53576, una vulnerabilidad de ejecución remota de código no autenticada con CVSS 10.0 en Kestra ≤1.3.20, causada por un bypass de autenticación por sufijo de ruta (AuthenticationFilter.java, endsWith("/configs")).
Un atacante que nombre el namespace y el ID de un flujo de trabajo como configs puede crear y ejecutar comandos de shell arbitrarios sin credenciales, como root, dentro del contenedor de Kestra. Corregido en 1.0.45 y 1.3.21. El mismo fallo también se reportó de forma independiente bajo CVE-2026-49869, que es el número incluido en el catálogo KEV de CISA vinculado a explotación real en el mundo real. Ambos deben citarse juntos, ya que las fuentes públicas y los escáneres pueden hacer referencia a cualquiera de los dos.
| Vulnerable | Kestra ≤ 1.3.20 (y anteriores a 1.0.45 en la línea 1.0.x) |
| Corregida | 1.0.45 / 1.3.21+ |
| CVE | CVE-2026-53576 |
| Aviso gemelo | CVE-2026-49869 - mismo fallo, incluido en KEV de CISA (en el mundo real) |
| Fecha | Evento |
|---|---|
| 2026-06-02 | Se publica Kestra 1.3.21; el changelog menciona un "posible bypass de autenticación en el filtro de autenticación" |
| 2026-06-03 | Se publica Kestra 1.0.45 en la línea 1.0.x |
| 2026-09-02 | CVE-2026-49869 (el aviso gemelo) se añade al catálogo KEV de CISA |
| 2026-09-22 a 09-24 | Esta reproducción en laboratorio, construcción de detección y validación entre capas |
Homelab autoalojado:
- Host Debian (nombre de host docker, kernel 6.12.107+deb13-amd64),
- Docker Engine 29.8.1.
- Kestra desplegado como la imagen oficial kestra/kestra:v1.3.20, accesible a través de un proxy inverso Caddy en kestra.int.atlasvec.com.
- Pila de telemetría bajo prueba: Falco (runtime/eBPF, a nivel de host),
- Suricata 8.0.3 IDS (espejo SPAN pasivo), reenviando hacia Splunk.
Antes de tocar nada, confirmé que el objetivo era realmente vulnerable y que la pila de telemetría estaba activa. También tomé una instantánea del estado previo al ataque para poder revertir una vez terminado.
Kestra ejecutando la versión vulnerable:

El propio contenedor, activo y accesible:

Las unidades de Falco cargadas en el host:

Falco emitiendo eventos activamente (modo eBPF moderno):

El servicio de Suricata activo:

Y su eve.json escribiendo eventos en vivo:

Aquí se alinean dos errores, no uno.
En primer lugar, el filtro de autenticación decide si una solicitud puede omitir la autenticación haciendo coincidir el final de la ruta de la solicitud:```java // AuthenticationFilter.java — the vulnerable check, confirmed against the self-hosted v1.3.20 source if (path.endsWith("/configs")) { // treated as a public, unauthenticated path }
Esa comprobación existe para exponer un único endpoint inofensivo, la configuración de la instancia pública. Como `endsWith` solo lee la cola de la cadena, no puede distinguir una ruta segura de cualquier otra ruta que termine de la misma manera.