Skip to content

GHSA-rh99-wc69-c255 - Contrast CopyFile policy symlink subversion

Contrast versions before 1.19.1 generated Kata agent policies whose CopyFile verification could be bypassed through symlinks. A malicious host process that can connect to the Kata agent VSOCK can issue CopyFile requests that write to arbitrary paths inside the guest root filesystem. That can overwrite security-sensitive files, change binaries that the workload later executes, or create a path to disclose sensitive workload data.

This matters for confidential container and secure context deployments because the host is explicitly outside the trusted computing base. A generated policy that allows host-provided file content to cross into the guest without a real resolved-path boundary breaks the same assumption SecurityRecipes expects from an MCP context layer: untrusted infrastructure can provide evidence or bytes, but must not be able to rewrite trusted execution state.

The Contrast GitHub advisory has no assigned CVE at the time this recipe was written. The related upstream Kata Containers issue is CVE-2026-41326 / GHSA-q49m-57vm-c8cc.

Affected versions

  • Vulnerable Contrast module: github.com/edgelesssys/contrast <1.19.1
  • Fixed Contrast module: github.com/edgelesssys/contrast 1.19.1+
  • Related upstream Kata issue: Kata Containers >=3.4.0, <3.29.0
  • Fixed upstream Kata version: Kata Containers 3.29.0+
  • High-risk condition: generated Kata agent policies permit CopyFile operations while a host-side process can reach the Kata agent VSOCK.

Indicator-of-exposure

  • The repository builds, vendors, pins, deploys, or documents Contrast before 1.19.1.
  • The repository runs contrast generate, commits generated policies, or distributes initdata/manifests produced by an older Contrast CLI.
  • Kubernetes workloads use Contrast confidential containers, Kata Containers, CoCo, or host-to-guest policy enforcement where the host is untrusted.
  • Generated policy, Rego, manifest, or runtime config references CopyFile, Kata agent policy, initdata, VSOCK, guest root filesystem paths, or host-provided content transfer.
  • Workloads keep secrets, model provider credentials, service mesh keys, data processing artifacts, or privileged binaries inside the guest filesystem.
  • Runtime ownership is split between platform, cluster, and application teams, making stale generated policies likely to survive a dependency-only upgrade.

Quick checks:

rg -n "edgelesssys/contrast|contrast generate|Contrast|kata-agent|Kata agent|CopyFile|VSOCK|vsock|initdata|agent policy|policy\\.rego" .
go list -m all | rg '^github.com/edgelesssys/contrast'
rg -n "kata-containers|io.containerd.kata|confidential|cvm|sev-snp|tdx|contrast.*policy|copy_file|copyfile" Dockerfile* docker-compose*.yml charts deploy k8s helm terraform .github .
find . -iname "*policy*.rego" -o -iname "*initdata*" -o -iname "*contrast*"

Remediation strategy

  • Upgrade every controlled Contrast CLI, module, container, deployment, and generated-policy toolchain to 1.19.1+.
  • Regenerate Kata agent policies, initdata, manifests, SBOMs, and deployment evidence with the fixed Contrast release. Do not assume upgrading the CLI protects workloads that still run old generated policy artifacts.
  • If this repository directly manages Kata Containers outside Contrast, upgrade affected Kata runtimes to 3.29.0+.
  • If immediate Contrast upgrade is blocked, apply the upstream policy-only Rego workaround through contrast generate --policy and document it as temporary containment until 1.19.1+ is deployed.
  • Restrict host access to the Kata agent VSOCK and treat host-provided CopyFile content as untrusted even after patching.
  • Re-attest and redeploy affected confidential workloads so the running guest state proves it consumed the regenerated policy.
  • Rotate secrets and rebuild affected workload images if host-side access to the agent was possible during the vulnerable window.

The prompt

Model context: this prompt was generated by GPT 5.5 Extra High reasoning.

You are remediating GHSA-rh99-wc69-c255 (Contrast-generated Kata agent
policies allow CopyFile policy subversion through symlinks). Produce exactly
one output:

- A reviewer-ready PR/change request that upgrades or contains affected
  Contrast/Kata policy generation, regenerates trusted artifacts, adds safe
  verification, and documents operator cleanup, or
- TRIAGE.md if this repository does not own an affected Contrast or Kata
  confidential-container deployment.

## Rules

- Scope only GHSA-rh99-wc69-c255 and the directly related upstream Kata
  CopyFile symlink issue (`CVE-2026-41326` / `GHSA-q49m-57vm-c8cc`).
- Treat guest filesystem contents, model/provider credentials, workload
  secrets, service mesh keys, attestation evidence, generated policy bundles,
  initdata, VSOCK endpoints, and host runtime logs as sensitive.
- Do not connect to a production or shared Kata agent VSOCK to prove exposure.
- Do not write test files into a real guest root filesystem, overwrite guest
  binaries, or exfiltrate workload data.
- Do not stop at updating `go.mod` if generated policies, initdata, manifests,
  images, or SBOMs remain stale.
- Do not auto-merge.

## Steps

1. Inventory every Contrast and Kata asset controlled by this repository:
   Go modules, lockfiles, vendored code, Contrast CLI download pins,
   Dockerfiles, Helm charts, Kubernetes manifests, Terraform, GitOps overlays,
   generated Kata agent policies, Rego files, initdata, attestation manifests,
   SBOMs, runbooks, and CI workflows.
2. Determine every resolved Contrast version. A target is vulnerable if it
   resolves to `github.com/edgelesssys/contrast <1.19.1` or uses a Contrast
   CLI/container/image before `1.19.1`.
3. Determine whether this repository directly manages Kata Containers. A
   direct Kata target is affected by the related upstream issue if it resolves
   to `>=3.4.0, <3.29.0`.
4. Identify generated artifacts that must be refreshed, including committed
   policy bundles, initdata, rendered manifests, attestation reference values,
   SBOMs, deployment evidence, and docs that tell operators how to generate
   policy.
5. Determine exposure without exploiting it:
   - Could a host-side process connect to the Kata agent VSOCK?
   - Do generated policies permit `CopyFile` requests?
   - Could `CopyFile` write into guest root paths that contain binaries,
     startup scripts, service config, credentials, or model/runtime data?
   - Are workloads running in confidential VMs where the host is explicitly
     untrusted?
   - Are old generated policies deployed after a dependency or CLI upgrade?
6. If the repository does not own Contrast/Kata deployment or generated policy
   artifacts, stop with `TRIAGE.md` naming the files checked, the likely
   runtime owner, the required Contrast fixed version `1.19.1+`, and the
   related Kata fixed version `3.29.0+`.
7. Upgrade controlled Contrast dependencies, CLIs, images, and deployment
   references to `1.19.1+`. Regenerate Go module state, binary checksums,
   container metadata, SBOMs, and dependency reports.
8. Regenerate every controlled Kata agent policy, initdata artifact,
   attestation manifest, rendered Kubernetes manifest, and deployment evidence
   with the fixed Contrast toolchain.
9. If direct Kata Containers are controlled here, upgrade to `3.29.0+` and
   regenerate runtime class, node image, operator, or containerd/Kata
   configuration artifacts.
10. If the Contrast upgrade cannot land immediately, add temporary containment
    using the upstream policy-only Rego fix through `contrast generate --policy`,
    block or restrict host access to the Kata agent VSOCK where this repository
    controls runtime policy, and mark the workaround as temporary.
11. Add safe verification:
    - version checks prove Contrast resolves to `1.19.1+`;
    - generated policy fixtures reject symlink-mediated `CopyFile` paths;
    - direct Kata targets resolve to `3.29.0+` when applicable;
    - rendered deployment artifacts no longer contain stale vulnerable policy;
    - tests use synthetic temporary fixtures and do not contact production
      agents, CVMs, or host VSOCK endpoints.
12. Add a PR body section named `GHSA-rh99-wc69-c255 operator actions` that
    states:
    - Contrast versions before and after the change;
    - whether direct Kata Containers are present and their versions;
    - which generated policies, initdata, attestation manifests, and deployment
      artifacts were regenerated;
    - whether any workload could have run with host-reachable Kata agent VSOCK;
    - which guest secrets, binaries, service configs, or model/runtime files
      could have been affected;
    - which node, runtime, VSOCK, workload, attestation, and deployment logs
      should be reviewed;
    - which secrets, service mesh credentials, images, or workloads require
      rotation, rebuild, or redeployment.
13. Run relevant validation: Go dependency resolution, unit tests, policy
    tests, Rego tests, manifest rendering, attestation/reference-value
    generation, container build, SBOM refresh, and dependency/security scans
    available in this repository.
14. Use PR title:
    `fix(sec): remediate Contrast CopyFile policy symlink subversion`.

## Stop conditions

- No Contrast, Kata Containers, confidential-container deployment, generated
  policy, initdata, or attestation artifact is controlled by this repository.
- The repository only consumes a platform-managed runtime and cannot safely
  upgrade or regenerate policy artifacts.
- A safe fix requires changing the confidential-container trust model or host
  runtime ownership boundaries; document the required product/security
  decision.
- Verification would require contacting a production Kata agent VSOCK,
  overwriting guest files, or reading real workload data.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No controlled Contrast dependency, CLI, image, SBOM, or deployment artifact remains below 1.19.1.
  • Every controlled generated Kata agent policy, initdata artifact, attestation manifest, and rendered deployment artifact was regenerated after the upgrade.
  • Direct Kata Containers targets, if present, resolve to 3.29.0+.
  • Tests or policy checks reject symlink-mediated CopyFile writes using only synthetic local fixtures.
  • Runtime containment addresses host access to the Kata agent VSOCK where this repository owns that boundary.
  • Operator actions identify stale deployments, possible guest takeover impact, logs to review, and credentials or workloads that may need rotation or rebuild.

Watch for

  • Updating Contrast source dependencies while committed policy/initdata artifacts remain generated by a vulnerable CLI.
  • Regenerating policy locally but leaving GitOps, Helm, or rendered manifests pinned to older artifacts.
  • Treating confidential computing attestation as sufficient when the measured policy itself permits unsafe host-to-guest file writes.
  • Proving the issue by writing into real guest paths or collecting real workload data.
  • Missing direct Kata Containers runtime pins because the repository uses RuntimeClass, node images, operator config, or containerd templates instead of Go modules.

References