FlawOpen

flawopen.com/Teardowns/cve-2026-106032-bedrock-agentcore-openapi-reference-ssrf

● CVE-2026-106032 · CVSS v4 5.7 · Media
Investigación · FlawOpen

CVE-2026-106032: SSRF en el importador OpenAPI de AgentCore

Hasta la versión 0.3.13, Starter Toolkit resolvía referencias OpenAPI externas al importar agentes. Datos manipulados de un grupo de acciones podían provocar solicitudes salientes o lectura de archivos locales. Actualiza a 0.3.14 o posterior, vuelve a importar los agentes afectados y reemplaza los artefactos generados.[1], [2], [3]

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina que el importador es un empleado que arma una carpeta siguiendo las referencias de un documento. El empleado vulnerable seguía cualquier referencia, incluso fuera de la carpeta o hacia archivos locales. Así, un agente aparentemente confiable podía hacer que el equipo buscara o leyera datos durante la importación. La corrección limita las referencias a páginas del mismo documento.[2], [7], [8]

Conceptos Clave y Términos

OpenAPI $ref
Puntero a un esquema o definición OpenAPI. Un fragmento apunta dentro del documento actual; una referencia externa puede señalar otro recurso.[1]
Prance ResolvingParser
Parser que Starter Toolkit utiliza para cargar y resolver referencias OpenAPI durante la importación.[2]
SSRF
Server-side request forgery: datos no confiables hacen que el software envíe solicitudes desde su propia posición de red.[7], [8]
CWE-918
El cweId principal estructurado del registro CVE es CWE-918 (Server-Side Request Forgery). La descripción también menciona CWE-73 por el aspecto de control externo de la ruta del archivo.[2], [3], [5]
CWE-73: External Control of File Name or Path
El mismo registro CVE menciona CWE-73, control externo del nombre o la ruta de archivo, por el aspecto de lectura de archivos locales. CWE-73 aparece en la descripción del tipo de problema; CWE-918 es el cweId principal estructurado.[3], [9]

Mapeos de marcos

Análisis de Causa Raíz

En 0.3.13, get_agent_info() pasaba el OpenAPI del grupo de acciones directamente a prance.ResolvingParser, sin restringir los tipos de resolución. En 0.3.14, el importador llama primero a assert_local_references_only(), que rechaza recursivamente valores $ref de tipo string que no comienzan con el prefijo de fragmento interno #/, y configura resolve_types=RESOLVE_INTERNAL. Así evita que el parser obtenga referencias OpenAPI externas por esta ruta de importación. Las pruebas del mantenedor verifican el rechazo antes de invocar el parser y cubren referencias HTTP, file, rutas absolutas y rutas de red, mientras permiten fragmentos internos. No extiendas este hallazgo a otras rutas del importador ni afirmes que bloquea todo acceso a red o archivos del proceso. La solución admitida es actualizar; la comparación muestra la frontera upstream, no una receta de explotación. El aviso de GitHub identifica a @seankohjs como quien reportó la vulnerabilidad; AWS agradece a Koh Jun Sheng su colaboración en la divulgación coordinada.[2], [7], [8], [1]

Flujo de Ataque Paso a Paso

Paso 1

Un principal de la misma cuenta modifica datos del agente

Un principal autenticado de la misma cuenta de AWS debe poder modificar el esquema OpenAPI del grupo de acciones de Bedrock Agent para colocar allí un valor de referencia externa diseñado para este fin. No es un ataque por internet sin autenticación.[2]

Paso 2

Otro usuario importa el agente

Un usuario ejecuta el flujo de importación de Starter Toolkit afectado. Las versiones vulnerables procesan el OpenAPI del grupo de acciones durante esta operación.[1], [2]

Paso 3

El parser resuelve una referencia externa

La versión 0.3.13 entregaba el documento a ResolvingParser sin limitar la resolución a referencias internas. Una referencia externa manipulada podía causar solicitudes salientes o acceso a archivos locales desde el entorno de importación.[7], [2]

Paso 4

Actualiza, vuelve a importar y reemplaza artefactos

Actualiza a 0.3.14 o posterior, vuelve a importar agentes importados con versiones afectadas y reemplaza los artefactos locales y desplegados. Cuando sea posible, migra del Starter Toolkit obsoleto a @aws/agentcore.[1], [8]

Código Fuente: Vulnerable vs. Seguro

Estos fragmentos proceden de las distribuciones oficiales 0.3.13 y 0.3.14. La corrección rechaza referencias $ref externas antes de ejecutar Prance y limita el resolver a referencias internas. Las pruebas upstream comprueban el rechazo previo al parser y la aceptación de fragmentos internos. Es una comparación acotada del código fuente, no un ejemplo de solicitud; actualiza el paquete en lugar de copiar los fragmentos.[7], [8], [2]

Fragmento de origen: Fragmentos del importador AgentCore, versiones 0.3.13 y 0.3.14

IMPLEMENTACIÓN VULNERABLE
# 0.3.13: el parser resuelve referencias del documento OpenAPI.
parser = ResolvingParser(
    spec_string=json.dumps(action_group["apiSchema"]["payload"])
)
action_group["apiSchema"]["payload"] = parser.specification
PARCHE SEGURO Y ROBUSTO
# 0.3.14: rechaza las referencias externas antes de analizar.
assert_local_references_only(action_group["apiSchema"]["payload"])
parser = ResolvingParser(
    spec_string=json.dumps(action_group["apiSchema"]["payload"]),
    resolve_types=RESOLVE_INTERNAL,
)

def assert_local_references_only(node, path: str = "$") -> None:
    if isinstance(node, dict):
        reference = node.get("$ref")
        if isinstance(reference, str) and not reference.startswith("#/"):
            raise ValueError(
                f"External OpenAPI references are not supported: {reference!r} at {path}."
            )
        for key, child in node.items():
            assert_local_references_only(child, f"{path}.{key}")
    elif isinstance(node, list):
        for index, child in enumerate(node):
            assert_local_references_only(child, f"{path}[{index}]")

Lista de Verificación de Seguridad para Ingeniería

Fuentes