When the image builder accepts the wrong letter: three flaws in apko (CVE-2026-42574 / -42575 / -42576) and what Wolfi build pipelines need today
On 9 May 2026 Chainguard published three security flaws in apko — the tool that, in Wolfi-based pipelines, builds OCI container images from declarative YAML files, without Dockerfiles, without layering tricks, without build containers. Three flaws all landing at a point that many builder vendors silently treat as trusted: the transition between a signed APK index and the individual .apk file that is then pulled into the image.
What has changed? Path traversal via symlink tar entries (CVE-2026-42574, fix 1.2.5), missing hash comparison of individual .apk against the signed index (CVE-2026-42575, fix 1.2.7), and a type-assert panic on non-RSA JWKS keys (CVE-2026-42576, fix 1.2.7). Who is affected? Every pipeline that runs apko in a version >=0.14.8 and <1.2.7 — effectively anyone building Wolfi images themselves. What should you read today? Patch path to 1.2.7, SBOM diff stage as the structural answer, detection on build hosts — in that order.
The 90-second summary
On 9 May 2026 Chainguard published three flaws in apko. CVE-2026-42574 (path traversal): a crafted .apk can install a TypeSymlink tar entry whose target sits outside the build root; a subsequent directory or file entry then walks the symlink and writes into host paths. Fix in apko 1.2.5.
CVE-2026-42575 (insufficient verification of data authenticity) is the structurally more unpleasant one: apko verifies the signature over APKINDEX.tar.gz but never compares the individual downloaded .apk against the checksum recorded in the signed index. Anyone who can substitute download responses — a compromised mirror, an HTTP repository, a poisoned CDN cache response — pushes arbitrary packages into the built image. Fix in apko 1.2.7.
CVE-2026-42576 (incorrect type conversion): DiscoverKeys in pkg/apk/apk/implementation.go performs a type assert of JWKS keys to *rsa.PublicKey without first checking the key type. A JWKS endpoint returning an EC key makes apko panic. The build aborts. Fix in apko 1.2.7.
Recommendation: pin directly to 1.2.7 (or higher), invalidate the pipeline cache, add an SBOM diff stage between apko build and apko publish as the structural answer to 42575, and a Falco or Tetragon rule on build hosts for 42574. Rotate backend API keys in the build pipeline if there is a window of suspicion.
What the three flaws are technically — and who is affected
The structural line behind all three
apko verifies the outer wrapper, not the individual content. The signed APKINDEX.tar.gz is verified because the Wolfi model anchors trust exactly there. But the jump from the verified index to the concrete .apk is exactly the point at which the trust model falls apart.
42574 shows this in the filesystem layout: a tar archive may set symlinks in apko, and nothing in the dirFS abstraction forces subsequent write operations to check the symlink target for containment within the build root. Anyone who patched an earlier apko version (before 1.1.1, closed by GHSA-5g94-c2wx-8pxw in February of this year) and then considered the topic settled, sees 42574 as the next iteration of the same structural class.
42575 is the actual sting. The Wolfi repository model signs the index — the list of available packages with their versions and hashes. The individual .apk is downloaded over HTTPS, and its authenticity should follow from comparing its computed control hash against the hash recorded in the signed index. Exactly this comparison is missing in getPackageImpl() in versions before 1.2.7. The index says “package X should have this hash”, the downloaded file has a different hash, and apko pushes it into the image anyway.
42576 is the simplest and didactically the most useful piece: an unconditional type assert without prior type check. The moment a JWKS provider switches to EC or Ed25519 — desirable from cryptographic hygiene — apko falls over. No RCE, no data leak, but an availability problem in a pipeline that by definition should run unattended overnight.
Who is affected
Directly affected is every pipeline running apko in a version >=0.14.8 and <1.2.5 (for 42574) or <1.2.7 (for 42575 and 42576). Anyone consuming Chainguard images from the public catalog is not directly affected — Chainguard builds those images with current apko in their own pipeline. Anyone building Wolfi images themselves — directly with apko, indirectly via melange plus apko, via Bazel rules (rules_apko), or via a CI-owned wrapper — is directly affected if the apko binary in use is older than 1.2.7. Anyone embedding apko as a library in their own Go programs must check whether the program suite was built with current apko modules — that is a go.sum audit, not a simple binary update.
Mitigation and immediate actions
The clean sequence is: first, version check in the pipeline (apko version); second, lift to 1.2.7 or higher (docker pull cgr.dev/chainguard/apko:latest or go install chainguard.dev/apko@v1.2.7); third, invalidate the pipeline cache — do not leave old apko binaries sitting in CI cache layers.
For Bazel builds with rules_apko: the rules pin a specific apko version whose pin must be updated in MODULE.bazel or WORKSPACE. bazel mod tidy alone does not pull that. For HTTP mirrors as a transitional solution: TLS migration and config verification, in case 1.2.7 cannot be wired into the Bazel pins immediately.
Detection and verification
Pipeline inventory: which apko versions actually run in which build jobs? A grep audit across GitHub Actions workflows finds most direct calls; an SBOM generation across the build containers finds indirectly embedded versions. Image SBOM against index: for 42575 the most robust detection is an SBOM inventory of the built image that compares each .apk with its hash against the Wolfi index at build time. A mismatch is proof of substitution. Falco rule or Tetragon TracingPolicy on the build hosts: anyone running apko in an ephemeral build environment can instrument writes outside the expected build root as an indicator for 42574.
Operator recommendation
Patch immediately if you built Wolfi images with your own apko version (<1.2.7) in the past 7 days and pushed them into a productively used registry. Maintenance window acceptable if apko is only used in nightly rebuilds whose output reaches production only after a manual approval gate. Pure consumer position if you pull exclusively cgr.dev/chainguard/* images from the public catalog — the fix is already applied in the provider's pipeline.
Mid-market DevOps teams that package TYPO3, Sylius or Symfony workloads into Wolfi images usually have exactly one apko call in the CI pipeline. Update the pipeline image version to cgr.dev/chainguard/apko:1.2.7, invalidate the CI cache, run a test build stage on a feature branch — the exercise takes 30 minutes. Anyone running nightly rebuilds sees the update in the next overnight batch. Larger organisations with Bazel- or Pulumi-based image definition sets need a two-stage approach: first lift the pin list to 1.2.7 and verify in an isolated replication build that the produced images are identical; then send the pin update through the normal release process via the standard quality gates. Declarative build hosts (NixOS, Talos, Flatcar) automatically eliminate a large part of the 42574 risk because the build root is structurally isolated; 42575 and 42576 affect them unchanged.
What we actually did
On 9 May at 18:30, after disclosure, we updated the apko pin in our own image pipeline and ran a replication build of the past three weeks of Wolfi image tags. Diff of the image SBOMs against the previously produced tags: identical except for the build timestamp field. That was our validation that the pipeline update introduces no content shifts.
In parallel we added an SBOM diff stage to the nightly build pipeline that compares every newly built .apk against the signed Wolfi index. That structurally closes 42575, independent of whether the underlying apko binary is still on an unpatched version. On the detection side we armed a Falco rule on our build hosts that flags writes outside the configured build root as an indicator for 42574.
Technical deep dive
The structural question behind 42575 is worth looking at more closely. The Wolfi model anchors trust in a signed index file because that is the single place where Chainguard controls cryptographic material. The individual .apk files are delivered via CDN endpoints whose integrity should follow from the TLS connection plus the subsequent hash comparison against the index. Exactly this second step was missing in getPackageImpl(). The code path parses the hash, holds it as ChecksumString(), computes the actual hash of the downloaded file — and never compares the two values.
The fix in 1.2.7 is the obvious line: if actualHash != expectedHash { return ErrChecksumMismatch }. This is the kind of mistake that should have surfaced in a code review — and that is therefore interesting as a lesson: not because it is novel, but because it shows that even a security-oriented project with a clear threat model had a gap at exactly that point. A trust chain does not fall apart on exotic cryptography but on the forgotten comparison line between two correctly computed values.
42574 has similar didactic clarity: dirFS as an abstraction is meant to prevent exactly what 42574 enables — writing outside the root. But MkdirAll and Symlink without containment checks in the path operations leak the abstraction at the point where it should protect. Any filesystem abstraction that permits symlinks while promising containment must resolve those symlinks before every operation.
Conclusion
apko is a remarkably clean and auditable codebase. The fact that three flaws arrive at once is not a sign of poor quality, but of an actively reviewed project: 42574 continues a line that began with GHSA-5g94-c2wx-8pxw in February of this year; 42575 is the kind of structural verification gap that can appear in any supply-chain tool; 42576 is the kind of type-assertion panic that surfaces in any Go codebase the moment someone varies the input.
The question is not whether apko is a trustworthy tool. The question is whether you reconstruct the second trust level — the comparison of the individual component against the signed index — in your own pipeline or rely on the tool doing it completely and without exception for you. This week we saw that it does not always do it. The structural answer is an own verification stage, not the next patch.
A personal background and technical details on hardening Wolfi build pipelines: ole-hartwig.eu.
Frequently asked questions on apko CVE-2026-42574 / -42575 / -42576
We consume Chainguard images from the public catalog — does this concern us?+
Directly no. Chainguard builds the cgr.dev/chainguard/* images with current apko in its own pipeline; the images in the public catalog are not affected. Pure consumers are structurally fine.
We only use melange and apko via Bazel rules — what exactly do we patch?+
Lift the apko pin in MODULE.bazel (or WORKSPACE) to v1.2.7 and run bazel mod tidy. Bazel rules pin a specific apko version that does not get pulled automatically — so this is an explicit pin-update step.
Why add an SBOM diff stage if 1.2.7 already closes 42575?+
Because the next comparable flaw will come. The structural weakness — verifying the individual component against the signed index — is a class that can show up in any supply-chain tool. An own hash-verification stage between build and publish protects independently of whether the next patch arrives in time.
Is 42574 only relevant if we control the .apk source ourselves?+
No — the flaw acts on every .apk that the apko build processes. As soon as you pull packages from the Wolfi repository or your own mirror without having verified their content yourself, the attack path is open. The containment property of the dirFS abstraction does not cover that in versions before 1.2.5.
We use HTTP mirrors for Wolfi — how urgent is the switch to HTTPS?+
Today. HTTP mirrors give every MitM attacker on the path the option to substitute download responses — which, with 42575 unmitigated and without hash verification, becomes direct package substitution. Switching to HTTPS is a minimum requirement; an SBOM diff stage is the structural complement.
We had GHSA-5g94-c2wx-8pxw closed in February — is 42574 new?+
Yes, 42574 is its own newly discovered variant of the same class. The February flaw was closed in apko 1.1.1; 42574 affects versions from 0.14.8 and is only fully addressed in 1.2.5. That shows that the containment layer in the dirFS abstraction remains structurally exposed — hence the recommendation for an own detection rule on the build hosts.
We audit, mitigate and validate your Wolfi build pipeline against apko CVE-2026-42574 / -42575 / -42576 — including SBOM diff stage and build-host detection
SBOM inventory of the existing image estate, stopgap rollout of the apko pin to 1.2.7, addition of a hash-verification stage between build and publish, PoC validation of the Falco or Tetragon detection on your build hosts — in that order, with documented status per step.
This is the operational routine from DevSecOps as a Service and our standard line for supply-chain hardening. If you build Wolfi images yourself — in-house at a DACH mid-market company, on a platform serving multiple tenants, or as a CI-owned wrapper around melange/apko — let's talk before the next productive push.

