CVE
CVE-2026-54174
CWE
CWE-345, CWE-354
Affected Surface
`chainguard.dev/apko` versions earlier than `1.2.9`, `chainguard.dev/melange` versions earlier than `0.50.4`, OCI image builds, Wolfi or APK-based build pipelines, and CI systems that fetched packages through mirrors, caches, or networks an attacker could tamper with, Platform engineering workflows that assumed signed `APKINDEX` validation alone proved the integrity of the package files expanded into the final filesystem
CVE-2026-54174 is one of the more useful build-chain disclosures from the last few days because it is not about a malicious package in the registry. It is about a verification model that stopped one layer too early. Before the fixed releases, apko and melange verified the signed APK control metadata but did not prove that the payload bytes actually unpacked into the image matched the package’s own datahash.
That difference sounds subtle until you translate it into attacker paths. If an attacker could tamper with a package fetch through a compromised mirror, poisoned cache, or man-in-the-middle position, they could swap the data section of an APK while leaving the already-checked control metadata acceptable. In other words, the image builder could still trust the index and package identity while expanding attacker-controlled files into the final filesystem.
Affected packages and fixed versions
The newly published July advisory trail and package-version queries agree on the version boundaries:
chainguard.dev/apko < 1.2.9 affected
chainguard.dev/apko >= 1.2.9 fixed
chainguard.dev/melange < 0.50.4 affected
chainguard.dev/melange >= 0.50.4 fixed
This matters well beyond one Go module import path. These tools sit in image-build and packaging workflows that often feed:
- OCI base images
- Wolfi or Alpine-style APK package assembly
- CI pipelines that materialize build roots from remote repositories
- internal mirrors and cache tiers that engineering teams treat as trusted by default
That is why the bug belongs on an AppSec radar. It is a package integrity problem in the application delivery path, not just a maintainer-only packaging concern.
Where the trust model stopped short
The advisory language is unusually crisp:
Previously, Apko verified the control section hash (.PKGINFO etc.)
against the signed APKINDEX, but never verified the data section hash
(the actual package files that get installed).
That last parenthetical is the whole story. The control section tells you package identity and metadata. The data section is what actually lands in the image:
signed APKINDEX
-> references package control hash
-> package fetched
-> control hash verified
-> data section expanded into image filesystem
Before the fix, the last step did not prove that the expanded package bytes matched the datahash carried in .PKGINFO. So the pipeline was validating the envelope and metadata more strongly than the payload that would actually become runtime files.
The fix shows exactly what was missing
The upstream apko fix is useful because it does not hand-wave about “improved integrity checking.” It shows the missing comparison in code. After decoding the package checksum and confirming the control hash, the fixed getPackageImpl path now reads package metadata and validates the data section explicitly:
pkgInfo, err := exp.PkgInfo()
if err != nil {
return nil, fmt.Errorf("reading pkginfo for %s: %w", pkg.PackageName(), err)
}
expectedDataHash, err := hex.DecodeString(pkgInfo.DataHash)
if err != nil {
return nil, fmt.Errorf("package %q has malformed datahash %q: %w", pkg.PackageName(), pkgInfo.DataHash, err)
}
if !bytes.Equal(expectedDataHash, exp.PackageHash) {
return nil, fmt.Errorf(
"package %q data hash mismatch: expected %x, got %x",
pkg.PackageName(),
expectedDataHash,
exp.PackageHash,
)
}
This is the key architectural point: the fix does not replace the control-hash check. It adds the missing second proof. After the change, both layers matter:
control hash matches signed APKINDEX
AND
data hash matches .PKGINFO's datahash
That dual check is what closes the substitution gap.
Why .PKGINFO matters here
The patch notes and tests show that the datahash field inside .PKGINFO is the bridge from package metadata to the actual payload bytes. The updated test helper now hashes the data section first, writes the correct datahash into .PKGINFO, and then verifies that tampering is rejected.
The relevant shape is:
.PKGINFO:
datahash = <hex-encoded sha256 of APK data section>
From a trust-boundary perspective, this means the package format already had the information needed to verify the payload. The vulnerable behavior was not missing cryptographic material; it was failing to enforce the comparison before using the package.
What an attack would look like
The advisory does not describe active exploitation, but the abuse path is concrete:
attacker compromises mirror / poisons cache / performs MITM
-> serves APK with intact control metadata path
-> swaps data section contents
-> builder verifies index-linked control hash
-> builder expands substituted files into the image
-> downstream image inherits attacker-controlled package contents
That is why this is a supply-chain integrity flaw instead of a narrow package-parser bug. The trust boundary being crossed is not “can the attacker crash the tool?” It is “can the attacker make the image builder install different files than the metadata review implied?”
For teams building containers from less-trusted mirrors, internal caches, or intercepting network devices, that distinction is security-critical.
Why AppSec teams should care
This issue belongs in the same class of discussions as the recent libzypp repository metadata traversal, even though the bug is technically different. Both issues show a recurring theme:
- package ecosystems encode trust in metadata
- build pipelines often stop verifying earlier than defenders assume
- the bytes that actually land on disk are what matter in the end
In a modern build environment, apko and melange are often part of the path that decides what goes into production images. If those tools can be induced to expand attacker-controlled package contents while still appearing to honor signed index metadata, the problem is no longer just a packaging-library bug. It becomes an image provenance problem.
Detection and scoping
Start by identifying whether your pipeline still uses affected versions:
go list -m chainguard.dev/apko chainguard.dev/melange
rg -n "chainguard\\.dev/(apko|melange)" go.mod go.sum
Then review how package fetches occur in the relevant build path:
rg -n "apk|apko|melange|wolfi|APKINDEX|mirror|cache" .github ci scripts build
The most important scoping questions are:
- were vulnerable
apkoormelangeversions used in image builds? - did those builds consume packages through an internal mirror, transparent cache, or network path that an attacker could tamper with?
- are the resulting images still deployed or used as base artifacts downstream?
Because the flaw is about what got installed, image provenance and rebuild history matter more than package-manager logs alone.
Remediation
Patch first:
- upgrade
chainguard.dev/apkoto1.2.9or later - upgrade
chainguard.dev/melangeto0.50.4or later - rebuild images produced by older vulnerable pipelines if the fetch path might have been exposed to tampering
Then tighten the trust boundary:
- review mirror, cache, and repository trust assumptions in CI
- prefer end-to-end provenance and immutable artifact flows over opportunistic live package fetches
- audit whether internal caches could have served stale or attacker-modified APK content
If you cannot rule out tampering on the fetch path, do not treat the upgrade alone as a full response. Rebuild and re-verify downstream images, because the question is not just whether the tool was vulnerable. It is whether the wrong package payload may already have been baked into artifacts you still trust.
What defenders should remember
The most useful lesson from CVE-2026-54174 is that integrity models fail in layers. Signed indexes and control metadata are valuable, but they are not enough if the actual installed payload is not proven against the package’s own data hash before use.
For AppSec, platform, and supply-chain teams, that makes this a high-signal July disclosure: it exposes a gap exactly where many organizations increasingly concentrate trust, inside automated image builders and packaging pipelines that sit between source code and production.
From research to remediation
Check whether this pattern exists in your codebase
Turn this research into a remediation workflow. Scan dependencies and package manifests for similar supply-chain risk, then prioritize fixes with reachability context.