You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sec(build): runtime base alpine:3.21.3 ships fixable CRITICAL/HIGH OS advisories, blocking an image-level Trivy gate #1842
Surfaced while implementing #1836 (scan the shipped image). Deliberately kept out of that PR, and filed here so it is not lost.
What
The pinned runtime base alpine:3.21.3 carries fixable CRITICAL and HIGH OS-package advisories today. Measured directly:
$ trivy image --severity CRITICAL,HIGH --ignore-unfixed --scanners vuln alpine:3.21.3
libssl3 CVE-2026-31789 CRITICAL heap buffer overflow from large X.509 certificate
libssl3 CVE-2025-15467 HIGH -> 3.3.6-r0
libssl3 CVE-2026-28387 HIGH -> 3.3.7-r0 (+ CVE-2025-69421, CVE-2026-28388/9/90)
musl CVE-2026-40200 HIGH 1.2.5-r9 -> 1.2.5-r11
zlib CVE-2026-22184 HIGH 1.3.1-r2 -> 1.3.2-r0
--ignore-unfixed is in that command, so every one of these has a published fix available.
The libssl3 CRITICAL is the notable one: a heap buffer overflow triggered by a large X.509 certificate, in a service that terminates TLS and connects to databases over TLS.
Why it is filed separately
#1836 adds govulncheck -mode=binary over the Go binaries in the shipped image, which catches the class that actually bit us twice: a stale Go toolchain (#1833) and a prebuilt third-party binary (#1835). It does not cover OS packages.
Trivy scan-type: image would cover them, and was deliberately not added in #1836 for a specific reason: gating on it would land red on day one for a problem that PR does not fix, and a non-gating version would print an unactionable wall on every PR, which is the "looks like coverage" pattern #1836 exists to avoid.
So the ordering is: bump the base, then add the OS-package scan. Doing it the other way round produces a red or ignored check.
Fix direction
Bump the runtime base to a current alpine:3.x patch release that clears the fixable set above, re-pinning by digest. Never drop the @sha256: pin to make the bump easy, and never guess a digest (a real digest went stale mid-flight during sec(build): build the shipped image on go1.26.6 to clear the stdlib CVEs #1835 because the upstream tag was re-pushed; the pin is what caught it).
Re-measure with the same command and confirm the fixable set is empty.
Both directions. Prove the new scan fails on a known-bad image (for example the current alpine:3.21.3 base) and passes on the bumped one. A scan step that always passes is worse than none, because it reads as coverage.
Allowlist on success: a check written as != "failure" reports success for cancelled and skipped.
Related: #1836 (Go binary scanning in the image), #1833 and #1835 (the two rounds this class of gap hid).
Surfaced while implementing #1836 (scan the shipped image). Deliberately kept out of that PR, and filed here so it is not lost.
What
The pinned runtime base
alpine:3.21.3carries fixable CRITICAL and HIGH OS-package advisories today. Measured directly:--ignore-unfixedis in that command, so every one of these has a published fix available.The
libssl3CRITICAL is the notable one: a heap buffer overflow triggered by a large X.509 certificate, in a service that terminates TLS and connects to databases over TLS.Why it is filed separately
#1836 adds
govulncheck -mode=binaryover the Go binaries in the shipped image, which catches the class that actually bit us twice: a stale Go toolchain (#1833) and a prebuilt third-party binary (#1835). It does not cover OS packages.Trivy
scan-type: imagewould cover them, and was deliberately not added in #1836 for a specific reason: gating on it would land red on day one for a problem that PR does not fix, and a non-gating version would print an unactionable wall on every PR, which is the "looks like coverage" pattern #1836 exists to avoid.So the ordering is: bump the base, then add the OS-package scan. Doing it the other way round produces a red or ignored check.
Fix direction
alpine:3.xpatch release that clears the fixable set above, re-pinning by digest. Never drop the@sha256:pin to make the bump easy, and never guess a digest (a real digest went stale mid-flight during sec(build): build the shipped image on go1.26.6 to clear the stdlib CVEs #1835 because the upstream tag was re-pushed; the pin is what caught it).scan-type: imageto CI, gating, alongside the govulncheck binary scan from sec(ci): nothing scans the container image we ship, only source; a baked-in vulnerable binary is invisible by construction #1836.Verification bar
Both directions. Prove the new scan fails on a known-bad image (for example the current
alpine:3.21.3base) and passes on the bumped one. A scan step that always passes is worse than none, because it reads as coverage.Allowlist on success: a check written as
!= "failure"reports success forcancelledandskipped.Related: #1836 (Go binary scanning in the image), #1833 and #1835 (the two rounds this class of gap hid).