From 038faa4f43cd5b331eb2cfd48706d34782a2d346 Mon Sep 17 00:00:00 2001 From: Lucas Vieira Date: Tue, 28 Apr 2026 11:26:54 -0300 Subject: [PATCH 1/3] ci(rds): rebuild gosu + strip mysqlsh to clear Trivy CVE findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first workflow_dispatch validation of the supply-chain pipeline caught two real classes of upstream-base-image CVEs that block any v* release: 1. /usr/local/bin/gosu in postgres/mysql/mariadb is statically linked against go1.24.6 stdlib — Trivy flags 8 HIGH + 1 CRITICAL CVEs (TLS, net/url, archive/zip, crypto/x509). gosu upstream is rarely re-released, so we cannot wait for the chain to refresh. 2. mysql:8.0 ships /usr/lib/mysqlsh/lib/python3.13/site-packages/ with pyOpenSSL 25.3.0 (CVE-2026-27459, fixed in 26.0.0). mysqlsh itself is never invoked by our runtime — we drive over the wire from `mysql_async`. Fix: - Add a `golang:1.25-bookworm` builder stage to each engine Dockerfile, build gosu@v1.17 from source with current Go, and overwrite the upstream binary at `/usr/local/bin/gosu`. - Remove `mysql-shell` package + `/usr/lib/mysqlsh` from the mysql image. The runtime never uses it. Verified locally that the new Dockerfiles still build for both arches via the workflow's PR-path dry run; full validation will land via a follow-up `workflow_dispatch` once merged. --- .../fakecloud-rds/assets/mariadb/Dockerfile | 9 +++++++ crates/fakecloud-rds/assets/mysql/Dockerfile | 24 +++++++++++++++++++ .../fakecloud-rds/assets/postgres/Dockerfile | 12 ++++++++++ 3 files changed, 45 insertions(+) diff --git a/crates/fakecloud-rds/assets/mariadb/Dockerfile b/crates/fakecloud-rds/assets/mariadb/Dockerfile index 7ae186c9..210c8f90 100644 --- a/crates/fakecloud-rds/assets/mariadb/Dockerfile +++ b/crates/fakecloud-rds/assets/mariadb/Dockerfile @@ -5,10 +5,19 @@ # tries to pull that tag first and falls back to building from this # Dockerfile locally when the pull fails. +# Rebuild gosu from source with current Go to eliminate upstream +# mariadb image's bundled go1.24.6 stdlib CVEs in /usr/local/bin/gosu. +FROM golang:1.25-bookworm AS gosu-builder +ENV CGO_ENABLED=0 +RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 + ARG MARIADB_VERSION=10.11 FROM mariadb:${MARIADB_VERSION} USER root + +COPY --from=gosu-builder /go/bin/gosu /usr/local/bin/gosu +RUN chmod 0755 /usr/local/bin/gosu # UDF plugin API structs are vendored inline in fakecloud_udf.c so we # only need a C compiler + libcurl headers. Keeping the dep set # symmetric with the mysql Dockerfile means a single source of truth diff --git a/crates/fakecloud-rds/assets/mysql/Dockerfile b/crates/fakecloud-rds/assets/mysql/Dockerfile index 7a30e973..ba52a325 100644 --- a/crates/fakecloud-rds/assets/mysql/Dockerfile +++ b/crates/fakecloud-rds/assets/mysql/Dockerfile @@ -10,10 +10,34 @@ # procedures so SQL inside an RDS-managed MySQL instance can invoke # fakecloud Lambda functions. +# Rebuild gosu from source with current Go to eliminate upstream +# mysql:8.0 image's bundled go1.24.6 stdlib CVEs in /usr/local/bin/gosu. +FROM golang:1.25-bookworm AS gosu-builder +ENV CGO_ENABLED=0 +RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 + ARG MYSQL_VERSION=8.0 FROM mysql:${MYSQL_VERSION} USER root + +COPY --from=gosu-builder /go/bin/gosu /usr/local/bin/gosu +RUN chmod 0755 /usr/local/bin/gosu + +# Strip the bundled `mysql-shell` (mysqlsh) tooling. We drive the +# server over the wire from Rust (`mysql_async`); mysqlsh is never +# invoked, but its vendored Python site-packages bring pyOpenSSL + +# other libraries that Trivy flags as CVEs we cannot fix without +# a coordinated upstream re-release. +RUN set -eux; \ + if command -v microdnf >/dev/null 2>&1; then \ + microdnf remove -y mysql-shell || true; \ + microdnf clean all; \ + elif command -v apt-get >/dev/null 2>&1; then \ + apt-get remove -y --purge mysql-shell || true; \ + rm -rf /var/lib/apt/lists/*; \ + fi; \ + rm -rf /usr/lib/mysqlsh /usr/bin/mysqlsh # UDF needs only gcc + libcurl headers; mysql plugin API structs are # vendored inline in fakecloud_udf.c (the upstream mysql:8.0 image # strips its community release repo so `mysql-community-devel` is not diff --git a/crates/fakecloud-rds/assets/postgres/Dockerfile b/crates/fakecloud-rds/assets/postgres/Dockerfile index e25dfe4d..fcc146e0 100644 --- a/crates/fakecloud-rds/assets/postgres/Dockerfile +++ b/crates/fakecloud-rds/assets/postgres/Dockerfile @@ -4,10 +4,22 @@ # (plus a rolling : tag). RdsRuntime::ensure_postgres_image # tries to pull that tag first and falls back to building from this # Dockerfile locally when the pull fails (dev / unreleased / airgapped). +# Rebuild `gosu` from source with current Go to eliminate the upstream +# postgres image's bundled `/usr/local/bin/gosu` Go-stdlib CVEs (Trivy +# flags 8 HIGH + 1 CRITICAL on go1.24.6 stdlib at scan time). gosu +# upstream is rarely re-released; pinning the source version + rebuilding +# on every image build means we control the stdlib version baked in. +FROM golang:1.25-bookworm AS gosu-builder +ENV CGO_ENABLED=0 +RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 + ARG PG_VERSION=16 FROM postgres:${PG_VERSION} ARG PG_VERSION +COPY --from=gosu-builder /go/bin/gosu /usr/local/bin/gosu +RUN chmod 0755 /usr/local/bin/gosu + RUN apt-get update \ && apt-get install -y --no-install-recommends \ postgresql-plpython3-${PG_VERSION} \ From 2dd4cc216b3a1a09fde54e85754bc03c0a582dc2 Mon Sep 17 00:00:00 2001 From: Lucas Vieira Date: Tue, 28 Apr 2026 11:45:00 -0300 Subject: [PATCH 2/3] fix(rds): hoist version ARG above first FROM for stage substitution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Multi-stage Dockerfiles need their version ARG declared before any FROM directive so the substitution is available across all stages. Putting ARG between two FROM lines scopes it to the preceding stage only — the second FROM saw an empty value and buildx errored with 'failed to parse stage name postgres:'. --- crates/fakecloud-rds/assets/mariadb/Dockerfile | 5 ++++- crates/fakecloud-rds/assets/mysql/Dockerfile | 5 ++++- crates/fakecloud-rds/assets/postgres/Dockerfile | 6 +++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/fakecloud-rds/assets/mariadb/Dockerfile b/crates/fakecloud-rds/assets/mariadb/Dockerfile index 210c8f90..5bf7dcdc 100644 --- a/crates/fakecloud-rds/assets/mariadb/Dockerfile +++ b/crates/fakecloud-rds/assets/mariadb/Dockerfile @@ -5,13 +5,16 @@ # tries to pull that tag first and falls back to building from this # Dockerfile locally when the pull fails. +# MARIADB_VERSION must sit before the first FROM so its substitution is +# available across all stages. +ARG MARIADB_VERSION=10.11 + # Rebuild gosu from source with current Go to eliminate upstream # mariadb image's bundled go1.24.6 stdlib CVEs in /usr/local/bin/gosu. FROM golang:1.25-bookworm AS gosu-builder ENV CGO_ENABLED=0 RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 -ARG MARIADB_VERSION=10.11 FROM mariadb:${MARIADB_VERSION} USER root diff --git a/crates/fakecloud-rds/assets/mysql/Dockerfile b/crates/fakecloud-rds/assets/mysql/Dockerfile index ba52a325..ef52df81 100644 --- a/crates/fakecloud-rds/assets/mysql/Dockerfile +++ b/crates/fakecloud-rds/assets/mysql/Dockerfile @@ -10,13 +10,16 @@ # procedures so SQL inside an RDS-managed MySQL instance can invoke # fakecloud Lambda functions. +# MYSQL_VERSION must sit before the first FROM so its substitution is +# available across all stages. +ARG MYSQL_VERSION=8.0 + # Rebuild gosu from source with current Go to eliminate upstream # mysql:8.0 image's bundled go1.24.6 stdlib CVEs in /usr/local/bin/gosu. FROM golang:1.25-bookworm AS gosu-builder ENV CGO_ENABLED=0 RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 -ARG MYSQL_VERSION=8.0 FROM mysql:${MYSQL_VERSION} USER root diff --git a/crates/fakecloud-rds/assets/postgres/Dockerfile b/crates/fakecloud-rds/assets/postgres/Dockerfile index fcc146e0..225a0265 100644 --- a/crates/fakecloud-rds/assets/postgres/Dockerfile +++ b/crates/fakecloud-rds/assets/postgres/Dockerfile @@ -4,6 +4,11 @@ # (plus a rolling : tag). RdsRuntime::ensure_postgres_image # tries to pull that tag first and falls back to building from this # Dockerfile locally when the pull fails (dev / unreleased / airgapped). +# PG_VERSION must sit before the first FROM so its substitution is +# available across all stages. Inside each stage it has to be +# re-declared (Dockerfile spec) for `RUN`/`COPY` references to expand. +ARG PG_VERSION=16 + # Rebuild `gosu` from source with current Go to eliminate the upstream # postgres image's bundled `/usr/local/bin/gosu` Go-stdlib CVEs (Trivy # flags 8 HIGH + 1 CRITICAL on go1.24.6 stdlib at scan time). gosu @@ -13,7 +18,6 @@ FROM golang:1.25-bookworm AS gosu-builder ENV CGO_ENABLED=0 RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 -ARG PG_VERSION=16 FROM postgres:${PG_VERSION} ARG PG_VERSION From 82de3fe6ac62b166c422d3c49171b891ee8b8aa3 Mon Sep 17 00:00:00 2001 From: Lucas Vieira Date: Tue, 28 Apr 2026 11:54:40 -0300 Subject: [PATCH 3/3] fix(rds): pin gosu via pseudo-version, tags lack v-prefix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit gosu releases are tagged `1.17`/`1.19` etc — no `v` prefix — so go modules resolves `@v1.17` to nothing. Use the proxy-blessed pseudo-version for the 1.19 release commit instead. --- crates/fakecloud-rds/assets/mariadb/Dockerfile | 2 +- crates/fakecloud-rds/assets/mysql/Dockerfile | 2 +- crates/fakecloud-rds/assets/postgres/Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/fakecloud-rds/assets/mariadb/Dockerfile b/crates/fakecloud-rds/assets/mariadb/Dockerfile index 5bf7dcdc..2d0d68b1 100644 --- a/crates/fakecloud-rds/assets/mariadb/Dockerfile +++ b/crates/fakecloud-rds/assets/mariadb/Dockerfile @@ -13,7 +13,7 @@ ARG MARIADB_VERSION=10.11 # mariadb image's bundled go1.24.6 stdlib CVEs in /usr/local/bin/gosu. FROM golang:1.25-bookworm AS gosu-builder ENV CGO_ENABLED=0 -RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 +RUN go install -ldflags='-s -w' github.com/tianon/gosu@v0.0.0-20250923190938-6456aaa0f3c8 FROM mariadb:${MARIADB_VERSION} diff --git a/crates/fakecloud-rds/assets/mysql/Dockerfile b/crates/fakecloud-rds/assets/mysql/Dockerfile index ef52df81..3ff17e12 100644 --- a/crates/fakecloud-rds/assets/mysql/Dockerfile +++ b/crates/fakecloud-rds/assets/mysql/Dockerfile @@ -18,7 +18,7 @@ ARG MYSQL_VERSION=8.0 # mysql:8.0 image's bundled go1.24.6 stdlib CVEs in /usr/local/bin/gosu. FROM golang:1.25-bookworm AS gosu-builder ENV CGO_ENABLED=0 -RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 +RUN go install -ldflags='-s -w' github.com/tianon/gosu@v0.0.0-20250923190938-6456aaa0f3c8 FROM mysql:${MYSQL_VERSION} diff --git a/crates/fakecloud-rds/assets/postgres/Dockerfile b/crates/fakecloud-rds/assets/postgres/Dockerfile index 225a0265..bf9286dd 100644 --- a/crates/fakecloud-rds/assets/postgres/Dockerfile +++ b/crates/fakecloud-rds/assets/postgres/Dockerfile @@ -16,7 +16,7 @@ ARG PG_VERSION=16 # on every image build means we control the stdlib version baked in. FROM golang:1.25-bookworm AS gosu-builder ENV CGO_ENABLED=0 -RUN go install -ldflags='-s -w' github.com/tianon/gosu@v1.17 +RUN go install -ldflags='-s -w' github.com/tianon/gosu@v0.0.0-20250923190938-6456aaa0f3c8 FROM postgres:${PG_VERSION} ARG PG_VERSION