漏洞

apko / melange CVE-2026-54174 APK 数据成员完整性缺口——箱单验过了,货箱却没对号

截至 2026 年 7 月 26 日审阅时,默认发布目标是 apko 1.2.25 与 melange 0.56.3,并在部署时重查官方受支持发行;1.2.9 与 0.50.4 只标记最早修复边界。升级后还要隔离旧缓存,以有效包正控制、控制摘要 mismatch 和数据摘要 mismatch 验收,因为旧版 getter 没有把 .PKGINFO.datahash 与实际 PackageHash 比较。

暖纸手绘的 APK 收货台,签名索引和控制成员已经通过检查,数据成员正在最后一道摘要比较前等待。
文章导航

研究依据固定来源复核 melange 公告、apko 完整性修复与测试、melange 依赖更新、Alpine APK v2 格式,以及防御性的包和镜像验证

来源melange 安全公告 / apko 与 melange 固定源码 / Alpine APK 格式文档 / SOSEC 源码复核

受影响的是 APK 新取包路径的成功条件。旧版 apko 已经从受信 APKINDEX 取得控制成员的预期摘要,也已经为实际数据成员计算 SHA-256;控制成员通过后,代码直接把展开对象交给缓存或调用者,没有执行第二次相等比较。能影响镜像、交付缓存或实际 fetch 响应的一方由此可以保留合法控制成员,同时替换进入构建根文件系统的数据成员。

1 先升级并隔离旧缓存:处置单从这里开始

结论:apko 低于 1.2.9、melange 低于 0.50.4 的取包环境进入处置范围。当前变更单默认部署 apko 1.2.25 与 melange 0.56.3;这组版本是截至审阅日的发行目标,部署时仍须重查官方发行与支持状态。apko 直接把仓库包安装进 rootfs;melange 的 build guest 与 test guest 通过 apko 获取依赖。兼容性回滚只能使用经过批准、携带同等数据比较修复并通过三组验收的制品。

升级前先暂停受影响环境从可变外部镜像、共享代理缓存和来源不明的本地缓存取包。需要调查的 APK、APKINDEX、缓存文件和 job 日志先做只读保全,再把旧缓存退出服务。临时 fetch 限制只能缩小谁有机会改变响应,仍需固定版本完成格式内的两次摘要比较。

1.1 三个连续 gzip 成员建立两段摘要关系

APK v2 包由连续 gzip 流组成:可选的 .SIGN 成员、包含 .PKGINFO 的控制成员,以及承载文件、目录、模式和链接的数据成员。melange v0.56.3 的emitDataSection() 第 407–441 行先压缩数据并计算 SHA-256,控制模板第 165–199 行把十六进制结果写入 .PKGINFO.datahash;随后EmitPackage() 第 522–592 行生成控制成员、为控制成员生成可选签名,并按签名、控制、数据的顺序组合最终文件。未签名单包则是控制、数据。

apko 的普通仓库路径由默认验证签名的仓库索引入口开始;第 308–425 行的签名关口在解析前执行,显式启用 ignoreSignatures 的环境不具备这个前提。APKINDEX 解析器第 189–197 行读取 Q1 后的 Base64 SHA-1;展开器第 453–574 行分别计算并保存控制成员的 ControlHash 与数据成员的 PackageHash。普通仓库路径依赖已认证索引与 Q1,不会为每个包重新验证可选的 .SIGN 成员。四个值形成下面两次比较:

受信预期实际观察来源与对象决策
decode(Q1),Base64 编码的 SHA-1ControlHash已验签 APKINDEX 声明控制 gzip;展开器对收到的控制 gzip 计算摘要第一关:不等即拒绝;相等后才信任控制成员内的字段
decode(.PKGINFO.datahash),十六进制编码的 SHA-256PackageHash已通过第一关的控制成员声明数据 gzip;展开器对收到的数据 gzip 计算摘要第二关:旧版遗漏;1.2.9 不等即关闭对象并返回错误

全文只依赖一个完整性不变量:decode(Q1) == ControlHash && decode(.PKGINFO.datahash) == PackageHash。第一关把索引连接到控制成员,第二关把已经认证的控制成员连接到数据成员。数据 tar 内部的 PAX 文件校验用于检查成员内部结构;能够替换整个数据成员的一方可以同时改写文件与同成员内的校验值,因此来源完整性仍由第二关决定。

1.2 代码位置、永久修复、临时控制与退出条件

变更单摘要:截至审阅日的发布目标为 apko 1.2.25 与 melange 0.56.3,部署时重查当前官方发行;1.2.9 与 0.50.4 保留为最低修复边界。以 go version -m、SBOM 或 provenance 确认 melange 实际链接 apko 1.2.25 或经批准的等效修复制品;旧进程缓存和磁盘缓存保全证据后退出,以空缓存启动,临时 fetch 只到批准的认证快照;有效包正控制保持文件语义,控制 mismatch 与数据 mismatch 分别失败,失败对象不得进入 cache、return、installation 或发布;失败 workspace 整体丢弃,高价值历史镜像重建并替换,直到旧 binary、module、cache、manifest 与下游 digest pin 全部清零或登记例外。

固定到修复父提交 a7f10d8972fa035714387d9621745397a2f4135c 后,defaultPackageGetter.GetPackage() 第 97–126 行负责缓存协调,getPackageImpl() 第 129–183 行负责缓存查询、fetch、展开和放行。旧实现于第 173–176 行只验证第一关;无磁盘缓存时第 178–180 行直接返回,有缓存时第 183 行发布新缓存对象。

修复提交 8d34c756b1acdec0d18c82247f900a54255500f5 保留同一 GetPackage() 入口,并把getPackageImpl() 扩展到第 129–208 行。第 173–186 行完成第一关,第 188–201 行从已认证控制成员解析 .PKGINFO、解码 datahash 并执行第二关;格式错误或任一 mismatch 都调用 exp.Close() 后返回错误。只有两关均通过,代码才在第 203–208 行返回对象或进入 cachePackage()

如果无法立即部署固定 getter,安全的临时状态是暂停受影响路径的远程取包与产物晋级。只收窄网络、只换镜像、只清空一次缓存或者只改版本字符串,都没有补上第二关。

暖纸手绘的 APK 装箱台展示数据、控制、签名的生产顺序,以及最终签名、控制、数据三个连续 gzip 成员的落盘顺序。
图 1:melange 先固定数据成员并写入 datahash,随后生成控制成员和可选签名;apko 的两次比较分别连接索引、控制和数据。
移动端可横向滑动查看完整图示。

2 漏洞位于新取包对象的成功分支

GetPackage()getPackageImpl() 第 152–231 行根据是否配置磁盘缓存决定直接执行或通过 singleflight 合并同一 URL 的并发请求,并先尝试磁盘缓存。缓存未命中后,doFetchExpandAndVerify() 第 260–303 行读取本地文件、HTTP 或 HTTPS 响应,展开 APK,再执行控制和数据两关。展开成功时,控制目录、数据 TarFS 与两份实际摘要都已经存在。

这里的状态变化是“可读对象”获得“可消费对象”资格。解析器成功只能说明连续 gzip 和 tar 结构可以打开;getter 的摘要比较决定这些字节能否被返回、缓存和安装。旧代码让第一关通过成为全部完整性条件,所以已经计算的 PackageHash 没有参与授权。

2.1 修复前:控制成员通过后立即 return 或 cache

修复父提交的第 168–171 行完成展开,第 173–176 行调用 verifyControlHash()。第一关失败会关闭 expanded object;第一关成功后,代码在无缓存配置时直接返回,在有缓存配置时调用 cachePackage()PkgInfo().DataHashPackageHash 已经存在于同一对象生命周期,却没有成为成功分支的条件。

第一关是真实且有效的验证:错误的 Q1 表示、Base64 和控制字节都会失败。因此,只有有效包和控制损坏包的测试套件会给人一种完整性已经闭合的印象。数据 mismatch 用例必须让控制成员保持原样,才能单独触发遗漏的边。

缓存命中还需要单独处置。最早修复提交的getPackageImpl() 第 142–145 行可以直接返回磁盘缓存对象;当前 v1.2.25 仍在第 200–204 行返回成功加载的缓存对象,而cachedPackage() 第 440–538 行负责从已存控制与数据文件恢复它。二进制升级不会让每个历史条目重新进入新取包的两关路径。本文因此把旧缓存隔离和空缓存重建列为升级步骤,历史对象保留一份只读证据副本后退出生产服务。

2.2 修复后:第二关进入 cache、return 与 installation 之前

1.2.9 在第一关成功后调用 exp.PkgInfo(),从已经认证的控制成员读取 DataHashhex.DecodeString() 负责表示转换;非十六进制、奇数长度等格式错误直接失败,空值或长度错误的可解码文本随后也无法与三十二字节 PackageHash 相等。

第二关失败与第一关失败使用相同的资源语义:关闭 expanded object、返回错误、停止当前对象。它不会变成普通网络重试,也不会交出半有效 TarFS。这个位置让新获取的不一致数据在缓存发布、package return 和安装消费之前失去资格。

当前 v1.2.25 的TestGetPackage_HashVerification 第 336–372 行从公共 GetPackage 入口覆盖有效包正控制、控制 mismatch 和数据 mismatch。有效包防止“全部拒绝”冒充修复;两项负控制分别证明旧关口仍在和新增关口确实独立生效。下游验收还应覆盖无效 Base64、无效十六进制、缺失 .PKGINFO、截断 gzip、签名与未签名布局,以及失败后没有晋级副作用。

暖纸手绘的旧版取包路径,APKINDEX 与控制成员已经比较,数据成员旁的 datahash 与 PackageHash 仍未连接到最终放行条件。
图 2:旧 getter 计算了数据摘要,却在成功分支中遗漏第二关;修复把这项比较放在新对象被缓存、返回和安装之前。
移动端可横向滑动查看完整图示。

3 可达性取决于谁能改变构建实际收到的 APK

维护者公告给出的前提是攻击者能够影响目标 builder 实际取得的 APK,例如源站或镜像失陷、交付缓存被投毒,或者取包链路遭到中间人修改。攻击者还要等待目标选择相应索引条目并发起 fetch。只知道仓库地址、只提交一份配置或者只具备只读仓库凭据,均不足以改变响应字节。

GitHub reviewed GHSA 给出 CVSS 3.1 8.3,向量为 AV:N/AC:H/PR:N/UI:R/S:C/C:H/I:H/A:HPR:N 描述攻击者无需易受影响 builder 的账户;镜像、代理或传输位置的控制仍是外部前提。UI:R 按 FIRST 语义指攻击者之外的人类参与,自动流水线在计划取包时同样形成运营窗口。AC:H 对应对象选择、交付位置与取包时机带来的条件。

3.1 TLS、镜像权限与缓存策略决定交付面

HTTPS、证书验证、受控 DNS、批准仓库 allowlist 和最小代理权限能够降低传输修改机会。源站、镜像或具备合法代理权限的系统失陷后,加密连接仍可能交付与已认证控制元数据不一致的数据,因此格式内验证始终保留。重定向到不同主机时还要重新核对认证头、信任策略和日志归属。

共享缓存和 fallback 会改变调查结果。缓存应把索引快照、架构和 APK 对象作为可复核的一组;若第一来源返回完整性错误,第二来源成功也不能抹去前一对象。完整性 mismatch 应保留来源、包名版本、job、索引快照和对象摘要,触发隔离与来源调查。

多仓库配置最终会解析成一个具体 RepositoryPackage 和 URL。记录配置列表还不够,事件证据需要保存求解器实际选中的仓库、镜像或代理、架构与时间。amd64 的一致结果不能为 arm64 对象签字,滚动索引当前正常也不能替代历史快照。

3.2 已确认能力是包文件替换,后续影响由真实构建决定

数据成员承载可执行文件、库、配置、证书、脚本、静态资源、权限和链接目标。旧 getter 可能把替换后的成员交给 rootfs 安装;这就是公共来源支持的核心能力。保留控制成员即可通过第一关,攻击过程无需仓库签名私钥,也无需制造 SHA-1 碰撞。

替换文件是否随后执行、接触凭据、影响编译结果、进入发布镜像或部署到运行环境,取决于包用途、guest 权限、构建步骤和发布动作。构建成功、registry push、部署和执行是四个独立状态,分别需要 job、provenance、registry 审计和运行时证据。对外结论应停在证据实际到达的位置。

apko 直接把包安装进目标 rootfs。melange v0.56.3 的buildGuest() 第 299–390 行通过 apko 锁定依赖、取得仓库索引并构建 build guest;Test.BuildGuest() 第 139–195 行以 apko 构建 test guest。替换的编译器或生成器可能影响后来产物,即使该工具没有留在最终镜像。只解析 YAML、生成元数据或者从未创建 guest 的 melange 使用方式不进入同一可达范围。

告警至少区分四种状态:资产运行受影响版本、固定版拒绝了 mismatch、历史对象经重算确认不一致、下游执行或发布已经确认。版本命中用于排查,第二关错误是高价值供应链信号;把两者混成同一严重结论会淹没真正异常。

4 根修复在 apko,melange 通过依赖升级取得它

apko 提交 8d34c756b1acdec0d18c82247f900a54255500f5 于 2026 年 4 月 28 日合入第二关,v1.2.9 同日发布。补丁没有改 APK v2 格式,也没有要求生产者生成新的签名种类;它消费已经存在的 datahashPackageHash。v1.2.9 标签位于后续提交 312a1507941c846eadc2ff22d1e2e1f7d82bebe7,所以根修复提交与发行标签承担不同证据角色。

melange 提交 9852e87fe4de7e2ca43d5029efd0948b2db5cae1chainguard.dev/apko 从 1.2.7 升到 1.2.9,v0.50.4 同日发布并包含该变化。相关源码在两个标签中保持同一机制:APK producer(v0.50.3v0.50.4)、index()、signer()与 tar writer()均没有为这项修复改变;生产者此前已经生成数据摘要,安全变化落在消费依赖。

截至 2026 年 7 月 26 日复核,发行目标 apko v1.2.25 的标签提交为 34cdf14533a0f0d7874cce7a7e514f937ffd7386,melange v0.56.3 的标签提交为 9ebf436f4e63634008f93e5676517f12a411d840,后者的go.mod 第 1–7 行明确要求 apko v1.2.25。这是审阅时的发布目标;部署动作重新核对官方版本和支持状态。

4.1 版本字符串之外还要验证实际模块与等效补丁

官方发行版可以用产品版本快速筛选,内部重建还要检查 go version -m、SBOM、构建 provenance、二进制 SHA-256 和源码提交。replace、vendor、fork 或复制到单仓库的源码可能让新产品版本仍携带旧 getter,也可能让旧语义版本含有等效修复。

等效 backport 的验收对象是同一成功条件:第一关成功后,从已认证控制成员读取并解码数据预期,第二关失败关闭对象并返回,成功后才允许新缓存、return 和 installation。例外记录应附固定源码范围、构建记录、二进制身份以及有效包正控制和两项 mismatch 回归结果。

go.sum 变化只说明模块内容记录更新,最终二进制可能受 build tag、图裁剪、vendor 和 replace 影响。发布工单需要把源模块图、构建命令、制品内模块信息与二进制摘要连接起来,才能证明执行路径实际包含修复。

4.2 决定性时间与发布制品验证

apko 1.2.9 与 melange 0.50.4 均于 2026 年 4 月 28 日发布;melange 仓库的维护者 GHSA 于 6 月 3 日公开;GitHub Advisory Database 于 7 月 10 日 21:43:05 UTC 发布 reviewed 全局条目,对应上海时间 7 月 11 日 05:43:05。修复制品早于全局入库两个多月,历史暴露窗口应按实际构建工具和对象证据计算。

发布页为 Linux amd64 与 arm64 提供架构对应的压缩包、checksum 清单、签名和证书。落地时先用发布方清单核对下载归档,再验证签名或证书,解包后检查二进制模块,最后把结果绑定到内部工具镜像 digest。逐架构归档具有各自摘要,不能把某个平台的校验值用于另一个平台,也不能用归档摘要代替制品内模块检查。

截至本次固定研究快照,GitHub 已把公告与 CVE-2026-54174 关联,CVE Services 的完整公开记录与 NVD 条目尚未形成可用技术来源。机制、版本范围、评分和修复判断由维护者 GHSA、reviewed GHSA 与固定源码支撑;登记状态只用于解释数据库覆盖。

5 历史调查要恢复当时的索引、对象与构建结果

固定版解决未来的新取包,历史构建仍需回答当时真正收到哪些字节。当前源站正常只能描述当前状态;受影响版本命中也只能描述代码暴露。调查应把某个 builder、某次索引选择、某个 APK 对象和具体 OCI 产物连成一条可重算的对象链。

5.1 先固定执行代码与交付视图,再重跑两关

资产盘点覆盖开发工作站、CI runner、构建服务、release 容器、复用 action 和内部工具镜像。每个位置记录 apko 或 melange 版本、二进制 SHA-256、嵌入模块、镜像 digest、构建时间和 owner;短生命周期 runner 由 job 元数据和执行镜像历史恢复。

随后恢复实际生效的 repository URL、mirror 顺序、架构、索引签名密钥、代理、lock、环境变量与命令行覆盖。对高价值构建保存当时 APKINDEX 及签名、实际 APK 字节、代理命中状态和 whole-object SHA-256。凭据在取证副本中脱敏,主机、路径、快照和对象身份必须保留。

对保留对象先认证索引快照,再重跑第一章表中的第一关与第二关。任何一关失败都隔离原件并停止引用该包;两关通过后,继续比较数据成员的路径、内容哈希、模式、所有者和链接,再对照 rootfs、SBOM、OCI layer、config、manifest、签名与 provenance。

整个 .apk 的 SHA-256 用于在对象存储、代理和 runner 之间识别同一次下载,它与控制成员摘要和数据成员摘要属于不同对象。whole-object 摘要变化只能定位到整个连续字节流发生变化;第一关与第二关负责指出哪段发布关系成立。

5.2 三类结论决定保留、重建与替换

第一类是已证明使用固定 getter、工具来源可验证且两关通过的构建;第二类是运行受影响代码、但保存对象和输出能够完成一致性复核的构建;第三类缺少执行版本、历史对象或来源证据。第三类进入优先重建队列,结论写成“无法重算”,不升级为已确认替换。

镜像级重建还要固定 repository snapshot、工具链、架构、locale、umask、压缩器和文件系统语义。完整 OCI digest 不相等时,逐项解释包版本、文件内容、tar 顺序、时间元数据和层生成步骤;无法解释的可执行文件、库、配置、权限与链接变化优先调查。

构建工具可能在中间阶段执行后被删除,多个包也可能覆盖同一路径。调查需要安装顺序、replaces 关系、build command 和产物 provenance,单看最终 SBOM 或 rootfs 会漏掉这类中间影响。多架构 manifest 则按每个平台分别复核,最后再决定是否替换聚合标签。

结案记录为每个高价值 artifact 保存同一组事实:运行的 getter、索引快照、实际 APK、两关结果、文件与镜像差异、发布和部署状态、替代 digest 以及旧对象撤回结果。缺失字段降低结论置信度,不能由 CVE 扫描器标签补齐。

6 干净重建与旧对象撤回共同关闭事件

升级二进制只改变下一次执行。完整关闭还需要保全证据、退出旧缓存、固定输入、从空工作区重建、解释差异、替换已发布 artifact,并阻止旧工具和旧 digest 回到发布面。这些动作由同一变更单跟踪,避免安全修复在构建、registry 或消费方之间断开。

6.1 从冻结输入到替换发布物

  1. 冻结受影响路径的新发布,保存需要调查的索引、APK、缓存、日志和产物;隔离旧缓存和来源不明对象。
  2. 部署固定 apko 与 melange,验证实际模块和二进制身份,以空进程缓存、空磁盘缓存和干净 workspace 启动。
  3. 选择已认证、尽可能不可变的 repository snapshot,逐架构记录解析版本、镜像或代理位置和对象摘要。
  4. 运行有效包、控制 mismatch、数据 mismatch 三组验收;随后重建高价值 guest 与 OCI 镜像,失败 workspace 整体丢弃。
  5. 解释包、文件、layer 与 manifest 差异;为已发布对象生成替代 digest,撤回复制 registry、浮动 tag、多架构 manifest、下游 pin 与离线副本中的旧对象。

回滚策略固定在“继续执行两关”这一安全属性上。新发行版若出现兼容问题,可以使用携带等效补丁的内部构建,或者暂停远程取包;恢复受影响 getter 会重新打开相同成功分支。构建策略应把最低安全模块与二进制 allowlist 写进 release gate。

替换一个浮动 tag 不会让已经拉取的 digest 消失。发布团队需要提供替代 digest、消费方清单和验证方式;无法联系的离线环境与长期 pin 作为未关闭对象保留。中心 registry 更新只完成中央侧替换,不能自动结案。

6.2 长期门禁分别观察完整性、构建与发布

CI 持续运行一项有效正控制和两项独立 mismatch 负控制。release gate 检查工具镜像 digest、SBOM 中的 apko 模块、来源提交与完整 provenance,再授权生产签名和 registry push。任何完整性错误都让当前 job 不可晋级,并保留失败对象与来源信息。

监控分别计数控制 mismatch、数据 mismatch、编码错误、解析错误和下载错误,字段至少包含仓库主机、包名版本、架构、索引快照、失败类别、builder binary、job 和发生时间。数据 mismatch 与同一对象在其他 runner、镜像和区域的结果关联,便于区分单点交付异常与上游发布错误。

仓库运营方可以按快照抽样重算两关,构建方则从消费端运行相同合同。保留策略让索引和 APK 覆盖同一调查窗口,失败 job 与成功发布日志共同留存。消费者比较受信元数据与它所描述的实际对象,并在下一项授权动作前阻止失败对象,摘要由此成为供应链控制。

暖纸手绘的恢复路线依次经过盘点、固定工具、隔离、快照、重建、比较和发布。
图 3:图中七个阶段依次是盘点、固定工具、隔离、快照、重建、比较和发布。
移动端可横向滑动查看完整图示。

研究记录

7证据、对象与来源

下面保留本文实际使用的标识、时间和原始材料,便于继续调查。

7.1研究对象

报告涉及的产品、行为者、技术、受影响对象和控制点。

CVECVE-2026-54174

apko 与 melange 的 APK 数据成员完整性校验不完整

受影响版本apko < 1.2.9

受影响 apko 范围;1.2.9 起修复

受影响版本melange < 0.50.4

受影响 melange 范围;0.50.4 起解析到修复版 apko

审阅时发布目标apko 1.2.25

截至 2026 年 7 月 26 日的默认部署目标;部署时重查

审阅时发布目标melange 0.56.3

截至 2026 年 7 月 26 日的默认部署目标;其 go.mod 要求 apko 1.2.25

修复提交8d34c756b1acdec0d18c82247f900a54255500f5

apko 根修复提交

校验条件PkgInfo.DataHash == APKExpanded.PackageHash

控制元数据声明与实际数据成员摘要必须相等

7.2事件时间

  1. apko 1.2.9 发布

    apko 合入数据摘要比较并发布 1.2.9;同日 melange 0.50.4 升级到该依赖。

  2. 维护者公告公开

    melange 仓库公开 GHSA-fpg8-7664-jc5q。

  3. GitHub 全局公告入库

    GitHub Advisory Database 于上海时间 05:43 发布并审核关联 CVE 的条目。

  4. SOSEC 固定源码复核完成

    生产、索引、展开、取包、缓存前关口、安装消费与发布对象完成逐项复核。

7.3来源与材料

  1. melange 维护者公告 GHSA-fpg8-7664-jc5qhttps://github.com/chainguard-dev/melange/security/advisories/GHSA-fpg8-7664-jc5q
  2. GitHub Advisory Database 审核条目https://github.com/advisories/GHSA-fpg8-7664-jc5q
  3. GitHub Advisory Database API 记录https://api.github.com/advisories/GHSA-fpg8-7664-jc5q
  4. CVE Services 编号状态https://cveawg.mitre.org/api/cve-id/CVE-2026-54174
  5. CVE Services 公开记录查询https://cveawg.mitre.org/api/cve/CVE-2026-54174
  6. NVD CVE API 查询https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-54174
  7. FIRST CVSS v3.1 规范https://www.first.org/cvss/v3-1/specification-document
  8. MITRE ATT&CK T1195.002https://attack.mitre.org/techniques/T1195/002/
  9. apko 修复提交 8d34c756https://github.com/chainguard-dev/apko/commit/8d34c756b1acdec0d18c82247f900a54255500f5
  10. apko PR #2206https://github.com/chainguard-dev/apko/pull/2206
  11. apko 1.2.9 发布页https://github.com/chainguard-dev/apko/releases/tag/v1.2.9
  12. 审阅时 apko 1.2.25 发布目标https://github.com/chainguard-dev/apko/releases/tag/v1.2.25
  13. apko v1.2.8 到 v1.2.9 固定比较https://github.com/chainguard-dev/apko/compare/v1.2.8...v1.2.9
  14. 修复前 package_getter.go 第 129–183 行https://github.com/chainguard-dev/apko/blob/a7f10d8972fa035714387d9621745397a2f4135c/pkg/apk/apk/package_getter.go#L129-L183
  15. 修复后 package_getter.go 第 129–208 行https://github.com/chainguard-dev/apko/blob/8d34c756b1acdec0d18c82247f900a54255500f5/pkg/apk/apk/package_getter.go#L129-L208
  16. apko APK 展开与摘要计算https://github.com/chainguard-dev/apko/blob/8d34c756b1acdec0d18c82247f900a54255500f5/pkg/apk/expandapk/expandapk.go
  17. apko 哈希验证回归测试https://github.com/chainguard-dev/apko/blob/8d34c756b1acdec0d18c82247f900a54255500f5/pkg/apk/apk/package_getter_test.go
  18. melange apko 依赖修复提交https://github.com/chainguard-dev/melange/commit/9852e87fe4de7e2ca43d5029efd0948b2db5cae1
  19. melange PR #2506https://github.com/chainguard-dev/melange/pull/2506
  20. melange 0.50.4 发布页https://github.com/chainguard-dev/melange/releases/tag/v0.50.4
  21. 审阅时 melange 0.56.3 发布目标https://github.com/chainguard-dev/melange/releases/tag/v0.56.3
  22. melange v0.50.3 到 v0.50.4 固定比较https://github.com/chainguard-dev/melange/compare/v0.50.3...v0.50.4
  23. melange buildGuest 的 apko 消费路径https://github.com/chainguard-dev/melange/blob/v0.50.3/pkg/build/build.go
  24. melange APK 生产实现https://github.com/chainguard-dev/melange/blob/2582b68ddc8ca21b08bf7b244a2ff60bcbcee88f/pkg/build/package.go
  25. melange APK 签名实现https://github.com/chainguard-dev/melange/blob/2582b68ddc8ca21b08bf7b244a2ff60bcbcee88f/pkg/sign/apk.go
  26. apk-tools 官方 APK v2 格式文档https://gitlab.alpinelinux.org/alpine/apk-tools/-/blob/90b974fd8510fbc2b3d6adde311ad1ba8754c728/doc/apk-v2.5.scd
  27. Alpine 包格式说明https://wiki.alpinelinux.org/wiki/Alpine_package_format
  28. Chainguard apko 与 melange 工具链概览https://edu.chainguard.dev/open-source/build-tools/apko/overview/