
Problema con AWS SAM CLI (CVE-2025-3047, CVE-2025-3048)
Este README proporciona un análisis detallado de dos vulnerabilidades de seguridad encontradas en la Interfaz de Línea de Comandos del Modelo de Aplicaciones Serverless de AWS (AWS SAM CLI) – CVE-2025-3047 y CVE-2025-3048 – junto con los problemas a nivel de código y sus correcciones. Ambas vulnerabilidades implican un manejo inadecuado de los enlaces simbólicos (symlinks) durante el proceso de compilación mediante contenedores Docker. Cada sección a continuación cubre un CVE con un resumen, el código afectado (con referencias al código fuente de SAM CLI), el parche y cómo resuelve el problema, y orientación sobre la remediación.
Estas fallas implican un manejo inadecuado de los enlaces simbólicos (symlinks) durante el proceso sam build --use-container. Ambos problemas afectan a los entornos de desarrollo locales (no impactan los servicios o recursos implementados de AWS), pero podrían permitir acceso no autorizado a archivos en la máquina host al abusar de la forma en que AWS SAM CLI procesa los enlaces simbólicos. Se recomienda encarecidamente actualizar AWS SAM CLI a las versiones parcheadas (1.133.0+ para CVE-2025-3047, y 1.134.0+ para CVE-2025-3048).
GHSA-px37-jpqx-97q9 es una vulnerabilidad de path traversal en AWS SAM CLI <= v1.132.0 que permitía el acceso no autorizado a archivos en la máquina host durante sam build --use-container. Al compilar una aplicación serverless dentro de un contenedor Docker, SAM CLI seguía los enlaces simbólicos del proyecto por defecto. Un atacante que pudiera colocar un enlace simbólico malicioso en el proyecto (apuntando a un archivo sensible del host) podría aprovechar los permisos elevados del contenedor Docker para que ese archivo se montara en el contenedor y se copiara a una ubicación accesible dentro del contenedor. En efecto, esto significaba que los archivos privilegiados del host (fuera del directorio del proyecto) podían leerse y exfiltrarse a través del contenedor de compilación. El problema se corrigió en v1.133.0. (Para preservar la compatibilidad hacia atrás en casos legítimos, SAM CLI v1.133.0 introdujo una bandera opcional --mount-symlinks para volver a habilitar el comportamiento anterior si fuera necesario).
Causa raíz y componente afectado: El problema central radica en cómo AWS SAM CLI monta los directorios del proyecto y sus enlaces simbólicos en el contenedor Docker utilizado para las compilaciones. En el código de AWS SAM CLI (módulo samcli.local.docker.container), antes de la corrección, todos los enlaces simbólicos de nivel superior en el directorio del proyecto se resolvían automáticamente y se montaban por bind en el contenedor con los mismos privilegios elevados que el proceso del contenedor. El contenedor se ejecuta como root por defecto, por lo que resolver y montar un enlace simbólico que apunte a una ruta sensible del host daría al contenedor acceso a ese archivo, algo que un usuario no privilegiado del host normalmente no tendría. El código vulnerable no restringía suficientemente qué enlaces simbólicos seguir/montar.
Específicamente, en la función que crea los montajes de volúmenes Docker para la compilación, SAM CLI trataba incondicionalmente los enlaces simbólicos como archivos/directorios reales para montar. La vulnerabilidad residía en la lógica de orquestación de contenedores de SAM CLI, concretamente en el método Container.create de samcli/local/docker/container.py. En las versiones vulnerables, este método siempre intentaba resolver y montar los destinos de los enlaces simbólicos del proyecto dentro del contenedor Docker, independientemente del contexto. El código problemático se muestra a continuación, de SAM CLI v1.132.0:
# samcli/local/docker/container.py (v1.132.0 - vulnerable snippet)
if self._host_dir:
mount_mode = "rw,delegated" if self._mount_with_write else "ro,delegated"
LOG.info("Mounting %s as %s:%s, inside runtime container", self._host_dir, self._working_dir, mount_mode)
_volumes = {
self._host_dir: {
"bind": self._working_dir,
"mode": mount_mode,
},
**self._create_mapped_symlink_files(), # Always resolve and mount symlinks (vulnerable)
}
En el código anterior, _create_mapped_symlink_files() escanea los enlaces simbólicos bajo el directorio del proyecto y los prepara para ser montados. Debido a que se incluía incondicionalmente, todos los enlaces simbólicos (incluidos los que apuntan fuera del proyecto) se montaban en el contenedor. (ver aws/aws-sam-cli#7865)
La falla aquí es que durante un sam build --use-container, SAM CLI trata los enlaces simbólicos como archivos para montar en el contenedor. Si un enlace simbólico apuntara, por ejemplo, a /etc/shadow en el host, el contenedor Docker (que podría ejecutarse con privilegios elevados) montaría ese archivo mediante bind. Esto es un path traversal basado en enlaces simbólicos clásico, que resulta en escalada de privilegios – los archivos del host a los que el usuario normalmente no tendría acceso podrían ser leídos por el contenedor y terminar en la salida de la compilación.
Parche (código corregido en v1.133.0): La corrección introduce una noción de contexto de compilación y desactiva la resolución de enlaces simbólicos durante las compilaciones en contenedores. En la versión parcheada, Container.create recibe un parámetro adicional que indica el contexto (BUILD vs INVOKE), y solo resolverá enlaces simbólicos si el contexto es invocación (cuando se ejecutan funciones localmente), no durante las compilaciones. A continuación se muestra el código corregido de la versión parcheada:
# samcli/local/docker/container.py (v1.133.0+ - patched snippet)
if self._host_dir:
mount_mode = "rw,delegated" if self._mount_with_write else "ro,delegated"
LOG.info("Mounting %s as %s:%s, inside runtime container", self._host_dir, self._working_dir, mount_mode)
mapped_symlinks = self._create_mapped_symlink_files() if self._resolve_symlinks(context) else {}
_volumes = {
self._host_dir: {
"bind": self._working_dir,
"mode": mount_mode,
},
**mapped_symlinks, # Only mount symlinks if explicitly allowed by context (not in build)
}
En el código parcheado, _create_mapped_symlink_files() está envuelto tras una comprobación de contexto. El nuevo enum ContainerContext define contextos como BUILD e INVOKE, y _resolve_symlinks(context) devuelve False para el contexto de compilación. Por lo tanto, mapped_symlinks será un diccionario vacío durante las compilaciones, lo que significa que ningún enlace simbólico se monta en el contenedor por defecto.
Referencia del cambio de código: La corrección se implementó en Pull Request#7865 (“fix: Resolve symlinks on local invoke only”) y se publicó como parte de v1.133.0. El diff de GitHub muestra la introducción de ContainerContext y la lógica de montaje condicional. Al no montar los destinos de los enlaces simbólicos durante la compilación, el contenedor ya no obtiene acceso a archivos fuera del directorio del proyecto. (Si un usuario realmente quiere permitir enlaces simbólicos a rutas del host, ahora debe optar por ello mediante la bandera --mount-symlinks, que se añadió después de esta corrección).
Cómo resuelve el parche el problema: Después del parche, los enlaces simbólicos del proyecto ya no se seguirán durante la fase de compilación. Simplemente permanecerán como enlaces simbólicos en el contenedor (apuntando a rutas que no se montarán) o se ignorarán, en lugar de ser reemplazados por el contenido de su destino. Esto cierra el agujero donde un atacante podría engañar al proceso de compilación para que copie archivos sensibles del host. En resumen, la vista del contenedor de compilación ahora se limita al propio directorio del proyecto (más los volúmenes explícitamente permitidos), eliminando la escalada de privilegios no intencionada.
Remediación: Todos los usuarios deben actualizar a AWS SAM CLI v1.133.0 o posterior para obtener esta corrección. Después de actualizar, el comportamiento predeterminado es seguro. Solo si confías explícitamente en tu proyecto y necesitas el comportamiento anterior deberías usar sam build --use-container --mount-symlinks. Para la mayoría de los desarrolladores, se recomienda dejar esta bandera desactivada (el valor predeterminado) para garantizar que los enlaces simbólicos no puedan salir del espacio de trabajo. También es una buena práctica revisar cualquier enlace simbólico en tus proyectos para asegurarte de que no apunte a ubicaciones sensibles.
GHSA-pp64-wj43-xqcr es una vulnerabilidad relacionada que afecta a AWS SAM CLI <= v1.133.0 (corregida en v1.134.0). Una vulnerabilidad en la caché de artefactos de compilación de AWS SAM CLI podría permitir que archivos sensibles se filtraran del contenedor de vuelta al espacio de trabajo del host después de una compilación. Si un proyecto incluía enlaces simbólicos, después de ejecutar sam build --use-container, los contenidos de los destinos de los enlaces simbólicos se copiarían en el directorio de caché de compilación local como archivos o carpetas normales. En efecto, un desarrollador sin acceso a ciertos archivos del host podría obtener acceso porque los contenidos de esos archivos terminan en la salida de compilación .aws-sam en el host. Por ejemplo, un enlace simbólico en el proyecto que apunte a /secret/config podría hacer que el contenido real de /secret/config apareciera en la carpeta .aws-sam/build del proyecto después de la compilación en contenedor, incluso si el usuario no pudiera leer /secret/config directamente.
Causa raíz y componente afectado: El núcleo de este problema estaba en cómo SAM CLI copiaba archivos desde el contenedor (o desde el proceso de compilación) al directorio de artefactos de compilación del proyecto local. La función responsable de copiar archivos se encuentra en samcli/lib/utils/osutils.py, específicamente en la utilidad personalizada copytree. En las versiones vulnerables, esta función usaba shutil.copy2 de Python sin especificar follow_symlinks=False, que por defecto sigue los enlaces simbólicos y copia el contenido de los archivos. El siguiente fragmento (de v1.133.0) muestra la lógica problemática:
# samcli/lib/utils/osutils.py (v1.133.0 - vulnerable snippet)
# ... inside osutils.copytree ...
else:
try:
shutil.copy2(new_source, new_destination) # follow_symlinks is True by default (vulnerable)
except OSError as e:
if e.errno != errno.EINVAL:
raise e
Aquí, si new_source es un enlace simbólico, shutil.copy2 resolverá el enlace y copiará el archivo de destino a new_destination. No había ninguna bandera para indicarle que preservara el enlace simbólico. Así, un enlace simbólico a un archivo sensible haría que el contenido de ese archivo apareciera en el directorio de destino. (ver aws/aws-sam-cli#7890)
En términos prácticos, imagina que el proceso de compilación creó un enlace simbólico config -> /etc/secret-config (quizás como parte de la superposición de dependencias o como resto del escenario de CVE-2025-3047). El código anterior copiaría el contenido de /etc/secret-config en la salida de compilación local como config. Un usuario local que no pudiera leer /etc/secret-config directamente ahora podría simplemente abrir el archivo en .aws-sam/build/.../config y ver su contenido.
Parche (código corregido en v1.134.0): La corrección fue sencilla: preservar los enlaces simbólicos en lugar de seguirlos al copiar. En shutil de Python, esto se hace pasando follow_symlinks=False. El código parcheado (v1.134.0) cambia la llamada de copia de la siguiente manera:
# samcli/lib/utils/osutils.py (v1.134.0 - patched snippet)
else:
try:
shutil.copy2(new_source, new_destination, follow_symlinks=False) # Do not follow symlinks (fixed)
except OSError as e:
if e.errno != errno.EINVAL:
raise e
Con follow_symlinks=False, si new_source es un enlace simbólico, la función copiará el propio enlace simbólico en lugar del archivo al que apunta. En otras palabras, la salida de compilación contendrá un enlace simbólico con el mismo destino, en lugar de un archivo real con el contenido del destino.
Referencia del cambio de código: El cambio se realizó en Pull Request#7890 (“fix: Keep symlinks when copying files after build”) y se publicó en v1.134.0. El diff de GitHub de este PR confirma la adición del parámetro follow_symlinks=False a shutil.copy2, junto con pruebas unitarias actualizadas para garantizar que los enlaces simbólicos se preserven. La descripción del PR señala explícitamente: “Symlinks will stop being transformed into copies of the files and keep their symlink status.” Esto significa que los artefactos de compilación contendrán enlaces simbólicos (que referencian las rutas de archivo originales) en lugar de copias no autorizadas de los datos de los archivos.
Cómo resuelve el parche el problema: Después de esta corrección, la copia de archivos posterior a la compilación de SAM CLI ya no filtra contenidos. Si se creó un enlace simbólico durante la compilación, permanecerá como enlace simbólico en la salida. El usuario local no obtendrá mágicamente acceso de lectura al contenido del destino: solo verá un enlace simbólico que sigue apuntando a la ruta original. A menos que el usuario ya tuviera permiso para leer el archivo de destino, el enlace simbólico en la salida es inofensivo (dará error si se desreferencia sin el acceso adecuado). Esencialmente, el impacto de confidencialidad se mitiga: los archivos sensibles no se materializan inadvertidamente en el espacio de trabajo del usuario. Esta corrección complementa el parche de CVE-2025-3047: detuvo que el contenedor tomara archivos del host mediante enlaces simbólicos; la corrección de CVE-2025-3048 evita que los que sí lograron pasar (o existían legítimamente) se persistan como archivos comunes en la salida.
Remediación: Los usuarios deben actualizar a AWS SAM CLI v1.134.0 o superior para obtener este parche. Una vez en v1.134.0+, el proceso de compilación preservará los enlaces simbólicos por defecto, corrigiendo esta vulnerabilidad. Después de actualizar, se recomienda limpiar y reconstruir cualquier aplicación SAM para asegurar que los artefactos de compilación almacenados en caché se regeneren bajo el nuevo comportamiento más seguro (el boletín de seguridad de AWS aconseja ejecutar un sam build --use-container fresco después de actualizar). No hay soluciones alternativas para este problema en versiones anteriores, aparte de eliminar manualmente los enlaces simbólicos sensibles o no usar compilaciones con contenedores, por lo que actualizar es la única solución robusta. En general, trate la carpeta de compilación local de SAM CLI como una salida sensible – con el parche ya no debería contener secretos inesperados, pero es una buena práctica vigilar lo que termina en sus artefactos de compilación.
Tanto CVE-2025-3047 como CVE-2025-3048 implican debilidades en el manejo de enlaces simbólicos que podrían provocar la exposición de archivos confidenciales durante las compilaciones locales. CVE-2025-3047 podría permitir que se leyeran archivos dentro del contenedor Docker (y potencialmente se copiaran hacia afuera), mientras que CVE-2025-3048 podría permitir que esos archivos terminaran en la salida local donde un usuario o atacante pudiera leerlos más tarde. Estas vulnerabilidades fueron calificadas con severidad moderada, ya que requieren cierta interacción del usuario (ejecutar una compilación en un proyecto malicioso), pero podrían resultar en un alto impacto de confidencialidad. Los parches coordinados garantizan que, por defecto, SAM CLI no siga los enlaces simbólicos durante las compilaciones en contenedores ni copie los destinos de los enlaces simbólicos a la salida.
Los desarrolladores y profesionales de DevSecOps que usan SAM CLI deben asegurarse de que su CLI esté actualizada (v1.134.0 o posterior) y permanecer cautelosos con proyectos que contengan enlaces simbólicos inesperados. Si mantienes versiones fork o personalizadas de SAM CLI, debes incorporar estas mismas correcciones. Al comprender estos cambios de código, se puede apreciar cómo un pequeño ajuste de lógica – como añadir una condición o un parámetro de función – puede cerrar un grave agujero de seguridad. Considere siempre la seguridad del manejo de archivos, especialmente cuando se trata de enlaces simbólicos e interacciones con contenedores, para prevenir problemas similares de path traversal en sus propios proyectos.
Referencias:
container.py y osutils.py que demuestran las correcciones