From d4e452b67b6cf78aff45415f80da3b12aa5ad5f5 Mon Sep 17 00:00:00 2001 From: Ben Date: Sat, 23 May 2026 14:59:42 +1000 Subject: [PATCH] fix(docker): SHA256-verify s6-overlay tarballs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR #30136 review flagged the s6-overlay install as a supply-chain regression vs the gosu source it replaced — `tianon/gosu` was digest-pinned via `FROM ...@sha256:...`, but the three new ADD/curl downloads had no integrity check at all. Pin all three tarballs (noarch, symlinks-noarch, per-arch) to upstream-published SHA256s via ARGs. Verification happens via `sha256sum -c` against a single checksum file (avoids a piped-shell hadolint DL4006 warning under dash). To bump S6_OVERLAY_VERSION, fetch the four `.sha256` files from the new release and update the ARGs — documented inline. If upstream artifacts are tampered with mid-build, the build now fails loudly at the verification step instead of silently producing a tainted image. --- Dockerfile | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d350dbeefba..eb5d9fb7e15 100644 --- a/Dockerfile +++ b/Dockerfile @@ -34,22 +34,38 @@ RUN apt-get update && \ # — splitting one URL per arch into two ADDs would download both on every # build and leave dead bytes in the cache. A single curl + arch-keyed URL # is simpler and cache-friendlier. +# +# Supply-chain integrity: every tarball is checksum-verified against the +# upstream-published SHA256. To bump S6_OVERLAY_VERSION, fetch the four +# `.sha256` files from the corresponding release and update the ARGs. The +# checksum lookup happens during build, so a compromised release artifact +# fails the build loudly instead of silently producing a tampered image. ARG TARGETARCH ARG S6_OVERLAY_VERSION=3.2.3.0 +ARG S6_OVERLAY_NOARCH_SHA256=b720f9d9340efc8bb07528b9743813c836e4b02f8693d90241f047998b4c53cf +ARG S6_OVERLAY_X86_64_SHA256=a93f02882c6ed46b21e7adb5c0add86154f01236c93cd82c7d682722e8840563 +ARG S6_OVERLAY_AARCH64_SHA256=0952056ff913482163cc30e35b2e944b507ba1025d78f5becbb89367bf344581 +ARG S6_OVERLAY_SYMLINKS_SHA256=a60dc5235de3ecbcf874b9c1f18d73263ab99b289b9329aa950e8729c4789f0e ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp/ ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-symlinks-noarch.tar.xz /tmp/ RUN set -eu; \ case "${TARGETARCH:-amd64}" in \ - amd64) s6_arch="x86_64" ;; \ - arm64) s6_arch="aarch64" ;; \ + amd64) s6_arch="x86_64"; s6_arch_sha="${S6_OVERLAY_X86_64_SHA256}" ;; \ + arm64) s6_arch="aarch64"; s6_arch_sha="${S6_OVERLAY_AARCH64_SHA256}" ;; \ *) echo "Unsupported TARGETARCH=${TARGETARCH} for s6-overlay" >&2; exit 1 ;; \ esac; \ curl -fsSL --retry 3 -o /tmp/s6-overlay-arch.tar.xz \ "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-${s6_arch}.tar.xz"; \ + { \ + printf '%s %s\n' "${S6_OVERLAY_NOARCH_SHA256}" /tmp/s6-overlay-noarch.tar.xz; \ + printf '%s %s\n' "${s6_arch_sha}" /tmp/s6-overlay-arch.tar.xz; \ + printf '%s %s\n' "${S6_OVERLAY_SYMLINKS_SHA256}" /tmp/s6-overlay-symlinks-noarch.tar.xz; \ + } > /tmp/s6-overlay.sha256; \ + sha256sum -c /tmp/s6-overlay.sha256; \ tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz; \ tar -C / -Jxpf /tmp/s6-overlay-arch.tar.xz; \ tar -C / -Jxpf /tmp/s6-overlay-symlinks-noarch.tar.xz; \ - rm /tmp/s6-overlay-*.tar.xz + rm /tmp/s6-overlay-*.tar.xz /tmp/s6-overlay.sha256 # Non-root user for runtime; UID can be overridden via HERMES_UID at runtime RUN useradd -u 10000 -m -d /opt/data hermes