OWASP: A03 2025 - Software Supply Chain Failures
¿Qué son los Software Supply Chain Failures?
Los Software Supply Chain Failures aparecen cuando existen debilidades o compromisos en los componentes, herramientas y procesos utilizados para construir, distribuir, actualizar o mantener software.
La superficie de ataque no se limita a librerías con vulnerabilidades conocidas. También comprende los sistemas y relaciones de confianza que permiten que código de terceros o artefactos externos terminen formando parte de una aplicación.
Entre otros elementos, deben considerarse:
- Dependencias directas y transitivas del frontend y backend.
- Frameworks, runtimes y componentes del sistema.
- Imágenes base y contenedores.
- Repositorios y registries de paquetes.
- Repositorios de código.
- Herramientas y secretos de CI/CD.
- Sistemas de build y distribución de artefactos.
- Plugins, módulos y componentes de terceros.
- Scripts y recursos ejecutables procedentes de terceros.
- Herramientas utilizadas durante el desarrollo y despliegue.
El objetivo de la evaluación es construir un inventario razonable de los componentes y relaciones de confianza que intervienen en la aplicación y determinar qué ocurriría si alguno de ellos fuera vulnerable, estuviera obsoleto, procediera de una fuente no confiable o pudiera ser manipulado.
En este artículo analizamos las siguientes áreas:
Fingerprinting de tecnologías y versiones
Dependencias JavaScript del cliente
Dependencias del backend
Repositorios públicos y secretos
Imágenes de contenedor y registries
Integridad y procedencia de recursos externos
Workstations de desarrollo, IDEs y extensiones
CI/CD y procesos de build
Fingerprinting de tecnologías y versiones
El fingerprinting no constituye por sí mismo un fallo de cadena de suministro, pero permite construir el inventario de componentes necesario para identificar dependencias vulnerables, obsoletas o no mantenidas.
Empieza identificando tecnologías visibles desde el exterior:
curl -sI "https://objetivo.com" | grep -Ei 'server|x-powered-by'
También puedes revisar:
- HTML y comentarios.
- JavaScript y source maps accesibles.
- Cookies.
- Cabeceras HTTP.
- Rutas características.
- Respuestas de error.
- Archivos estáticos y nombres de bundles.
- Metadatos publicados por la aplicación.
La herramienta concreta es secundaria. Lo importante es construir relaciones verificables del tipo:
componente → versión → función utilizada → exposición → vulnerabilidades conocidas
Validación de versiones
No reportes una vulnerabilidad conocida únicamente porque una herramienta haya identificado de forma aproximada un producto o una versión.
Comprueba:
- Si la versión es exacta, aproximada o simplemente inferida.
- Si el componente identificado está realmente presente en producción.
- Si la funcionalidad afectada por la vulnerabilidad se utiliza.
- Si dicha funcionalidad está habilitada.
- Si el componente es alcanzable desde el contexto del atacante.
- Si se cumplen las precondiciones necesarias.
- Si existen mitigaciones que impidan el vector concreto.
La identificación de una versión vulnerable constituye un indicio. La explotabilidad y el impacto deben evaluarse teniendo en cuenta cómo participa ese componente en la aplicación.
Dependencias JavaScript del cliente
Revisa los scripts cargados por la aplicación y determina qué dependencias forman parte del código ejecutado en el navegador.
Una comprobación sencilla puede ser:
curl -s "https://objetivo.com" | grep -oE 'src="[^"]+\.js[^"]*"'
Busca especialmente:
- Librerías cuya versión pueda determinarse.
- Bundles que contengan dependencias antiguas.
- Dependencias abandonadas o sin mantenimiento.
- Scripts procedentes de dominios externos.
- Versiones duplicadas de una misma librería.
- Dependencias con vulnerabilidades conocidas relevantes para el uso que hace la aplicación.
Cuando sea posible, diferencia entre una librería simplemente presente en el bundle y código que realmente ejecuta la funcionalidad vulnerable.
No consideres automáticamente explotable una vulnerabilidad únicamente por identificar la dependencia: verifica si la aplicación utiliza la funcionalidad afectada y si se cumplen las condiciones necesarias.
Dependencias del backend
Cuando el alcance proporcione acceso al código fuente, repositorio, manifests o artefactos de build, revisa las dependencias utilizadas por el servidor.
Ejemplos:
npm audit
pip-audit -r requirements.txt
composer audit
Revisa tanto dependencias directas como transitivas, ya que una aplicación puede incorporar código vulnerable a través de una dependencia que no aparece directamente en el manifest principal.
Presta atención a archivos como:
package.json
package-lock.json
yarn.lock
pnpm-lock.yaml
requirements.txt
poetry.lock
Pipfile.lock
composer.json
composer.lock
pom.xml
build.gradle
Cargo.lock
go.mod
go.sum
Los archivos de bloqueo resultan especialmente útiles para determinar qué versiones concretas fueron resueltas durante el proceso de build.
Prioriza:
- Dependencias presentes en runtime.
- Componentes directamente expuestos.
- Dependencias transitivas relevantes.
- Componentes sin mantenimiento.
- Versiones obsoletas.
- Vulnerabilidades cuyas precondiciones se cumplen.
- Versiones efectivamente utilizadas en el artefacto desplegado, no únicamente las declaradas en el repositorio.
Una dependencia utilizada exclusivamente durante desarrollo o testing puede presentar un riesgo diferente de una librería cargada por el proceso que ejecuta la aplicación en producción.
Inventario y SBOM
Cuando esté disponible, revisa también el Software Bill of Materials (SBOM) del producto.
Un SBOM puede ayudar a relacionar la aplicación con sus componentes directos, las dependencias transitivas que incorpora, las versiones concretas resueltas durante el build y el artefacto que finalmente se despliega.
El objetivo es poder determinar con precisión qué componentes forman parte del software que finalmente llega a producción.
Repositorios públicos y secretos relacionados con la cadena de suministro
Revisa repositorios públicos o accidentalmente expuestos pertenecientes a la organización cuando puedan revelar información relacionada con el proceso de desarrollo, construcción o distribución.
Busca, entre otros:
- Tokens de CI/CD.
- Credenciales de registries.
- Tokens de gestores de paquetes.
- Claves utilizadas para publicar artefactos.
- Secretos eliminados en commits posteriores.
- Configuraciones de build.
- Archivos de workflow.
- Referencias a registries internos.
- Credenciales utilizadas por herramientas de automatización.
- Configuraciones con permisos excesivos.
Si el alcance permite revisar una copia local del repositorio:
git log --all --oneline
No limites la revisión al estado actual de los archivos. Información sensible eliminada posteriormente puede continuar presente en commits anteriores o en otras referencias del repositorio.
Para localizar secretos pueden utilizarse herramientas de detección sobre una copia autorizada.
Validación
La aparición de un secreto no demuestra automáticamente que continúe siendo válido.
Documenta:
- Dónde aparece.
- Su antigüedad aproximada.
- El servicio al que parece pertenecer.
- Los privilegios que aparentemente concede.
- Si continúa formando parte del proceso actual.
- Si existen indicios de rotación o revocación.
Red Team OPSEC
Evita utilizar secretos encontrados contra servicios externos salvo autorización explícita.
La existencia y el contexto de un secreto pueden ser suficientes para documentar la exposición sin utilizarlo para modificar repositorios, artefactos o sistemas de terceros.
Imágenes de contenedor y registries
Cuando las imágenes o registries formen parte del alcance, revisa tanto el contenido de las imágenes como su procedencia y proceso de publicación.
Presta atención a:
- Paquetes con vulnerabilidades conocidas.
- Dependencias obsoletas o sin mantenimiento.
- Secretos introducidos durante el build.
- Archivos sensibles presentes en capas históricas.
- Imágenes base antiguas.
- Herramientas de desarrollo innecesarias incluidas en producción.
- Configuraciones inseguras.
- Imágenes procedentes de fuentes no confiables.
- Falta de trazabilidad entre imagen, build y commit.
- Uso de tags mutables o ambiguos cuando dificulten determinar qué artefacto se encuentra realmente desplegado.
Ejemplos sobre una imagen explícitamente incluida en el alcance:
docker history objetivo/imagen:tag --no-trunc
trivy image objetivo/imagen:tag
Un resultado de análisis que indique la presencia de un CVE no demuestra automáticamente que el servicio desplegado sea explotable.
Relaciona siempre el paquete vulnerable con la imagen que lo contiene, el proceso que realmente lo utiliza, la funcionalidad afectada y la superficie desde la que podría alcanzarse. De esta forma evitas asumir explotabilidad únicamente porque un paquete aparezca dentro de la imagen.
Cuando sea posible, utiliza identificadores inmutables, como el digest de la imagen, para determinar con mayor precisión qué artefacto se está analizando.
Integridad y procedencia de recursos externos
Identifica scripts y otros recursos ejecutables que la aplicación obtiene de terceros:
<script src="https://cdn.example.com/library.js"></script>
La relación de confianza aparece cuando la aplicación depende de un proveedor externo para obtener un recurso que posteriormente se ejecutará dentro del contexto del usuario. Si ese proveedor o el mecanismo de distribución se ve comprometido, el código recibido puede terminar ejecutándose con la misma confianza que los recursos propios de la aplicación.
Determina:
- Qué tercero controla el recurso.
- Si el recurso puede cambiar sin intervención de la organización.
- Si se utiliza una versión fija o una referencia mutable.
- Qué privilegios obtiene el código una vez ejecutado.
- Si existen mecanismos para verificar su procedencia o integridad.
- Qué impacto tendría un compromiso del proveedor.
La ausencia de controles adicionales de integridad puede aumentar el riesgo, pero debe valorarse en contexto.
No todos los recursos externos presentan la misma criticidad: un script ejecutado dentro del contexto de seguridad de la aplicación tiene implicaciones diferentes de una imagen o una hoja de estilos.
Nota de clasificación
Cuando el problema concreto consiste en aceptar o ejecutar código externo sin verificar adecuadamente su integridad, el hallazgo también puede encajar en A08:2025 Software or Data Integrity Failures.
A03 se centra en la seguridad global de la cadena de suministro, mientras que A08 aborda de forma más específica los límites de confianza y la verificación de integridad de código, software y datos.
Workstations de desarrollo, IDEs y extensiones
La cadena de suministro no termina en los repositorios o pipelines. Los equipos de desarrollo, IDEs, extensiones y herramientas utilizadas para modificar o construir software también forman parte del entorno de confianza.
Durante una evaluación con acceso autorizado a estos entornos, presta atención a:
- Extensiones de IDE procedentes de fuentes no confiables.
- Plugins con permisos amplios sobre código o credenciales.
- Herramientas de build instaladas fuera de mecanismos controlados.
- Credenciales de desarrollo almacenadas localmente.
- Tokens de acceso a repositorios, registries o CI/CD.
- Software obsoleto o sin mantenimiento.
- Dependencias o binarios descargados desde ubicaciones no verificadas.
- Ausencia de controles sobre cambios realizados en herramientas de desarrollo.
Una extensión comprometida puede modificar código, capturar secretos o alterar artefactos antes de que entren en el pipeline.
Desde Red Team, el interés principal está en determinar si comprometer una estación de trabajo o herramienta de desarrollo permitiría obtener acceso al repositorio, influir en el pipeline, modificar artefactos o alcanzar finalmente producción.
No es necesario modificar código real para demostrar el riesgo. Si el contexto comprometido dispone de acceso suficiente para introducir cambios o recuperar secretos utilizados posteriormente por la cadena, la exposición puede documentarse con una validación mínima.
Red Team OPSEC
Evita modificar configuraciones, extensiones o repositorios reales de desarrolladores cuando los permisos y relaciones de confianza ya permitan demostrar el impacto.
No utilices secretos recuperados desde estaciones de trabajo para alterar artefactos o despliegues salvo autorización expresa.
CI/CD y procesos de build
Cuando el repositorio o la configuración del pipeline formen parte del alcance, analiza cómo pasa el código desde una contribución hasta convertirse en un artefacto desplegado.
Revisa:
- Quién puede modificar el código fuente.
- Quién puede modificar los workflows o pipelines.
- Quién puede iniciar builds.
- Qué eventos disparan automáticamente ejecuciones.
- Qué código se ejecuta durante cada etapa.
- Qué secretos están disponibles en cada job.
- Si los secretos están limitados por entorno.
- Si contribuciones externas pueden provocar ejecución de código con privilegios internos.
- Si existe separación de funciones entre desarrollo y promoción a producción.
- Cómo se generan y almacenan los artefactos.
- Si un artefacto puede modificarse después de haber sido construido.
- Si producción reconstruye el software o promociona el mismo artefacto previamente validado.
- Si existe trazabilidad entre código, build, artefacto y despliegue.
Una forma útil de modelar el proceso consiste en seguir el recorrido desde el commit hasta el despliegue: qué pipeline lo procesa, qué dependencias incorpora, cómo se realiza el build, dónde se almacena el artefacto y desde qué registry termina promocionándose a producción.
En cada transición debes preguntarte:
¿Puede una entrada o actor no confiable modificar aquello que terminará ejecutándose en producción?
También interesa determinar si el compromiso de un elemento permite avanzar hacia el siguiente. Por ejemplo, acceso a un repositorio podría permitir modificar un workflow; ese workflow podría exponer un secreto de publicación; y ese secreto podría proporcionar acceso al registry desde el que se distribuyen artefactos hacia producción.
Rollouts escalonados y reducción de impacto
Incluso cuando una actualización procede de un proveedor legítimo, un compromiso del proveedor o un artefacto defectuoso puede introducir riesgo.
Los mecanismos de despliegue escalonado, canary releases o promociones progresivas permiten reducir el impacto de una actualización comprometida al limitar inicialmente el número de sistemas afectados.
Un despliegue progresivo puede comenzar en un entorno de prueba, continuar con un conjunto canary o un grupo reducido de sistemas y ampliarse únicamente después de comprobar que el comportamiento es el esperado.
Durante una revisión del proceso de distribución, comprueba si las actualizaciones o nuevas versiones se despliegan directamente en todo el entorno o si existe alguna etapa intermedia que permita detectar comportamientos anómalos antes de una promoción completa.
La ausencia de un rollout escalonado no constituye automáticamente una vulnerabilidad, pero puede aumentar el impacto de un compromiso de la cadena de suministro al permitir que un artefacto malicioso alcance simultáneamente una gran parte de la infraestructura.
Red Team OPSEC
No publiques paquetes, imágenes o versiones utilizando nombres pertenecientes a la organización.
No utilices tokens de CI/CD, repositorios o registries para modificar código o artefactos salvo autorización expresa.
Evita disparar pipelines que puedan generar despliegues, publicar artefactos o producir cambios en producción cuando la exposición pueda demostrarse mediante revisión de configuración o una validación de menor impacto.