140 lines
9.0 KiB
Markdown
140 lines
9.0 KiB
Markdown
# Runtime image remediation follow-up — 8 September 2026
|
|
|
|
Canonical tracking: [Meta #52](https://git.add-ideas.de/GovOPlaN/govoplan/issues/52)
|
|
and [website #9](https://git.add-ideas.de/add-ideas/addideas-govoplan-website/issues/9).
|
|
This addendum supplements the [original audit](RUNTIME_IMAGE_AUDIT_2026-09-08.md);
|
|
it does not replace that historical baseline or lift either publication or
|
|
deployment gate. The immutable 0.1.45 release and `catalog-v0.1.45` are unchanged.
|
|
|
|
## Source change and candidate decisions
|
|
|
|
New installer specifications now use
|
|
`haproxy:3.2.23-alpine@sha256:6343ce34a132a5dceaa24767d739df2bd519f8f7c1079ae39e4821334e8eb42e`.
|
|
This is a patch update from 3.2.21 within the supported
|
|
[3.2 LTS branch](https://www.haproxy.org/), keeping Alpine 3.24.1.
|
|
The [publisher's exact build source](https://github.com/docker-library/haproxy/blob/7a5c202cde713867a737033dca56e7a211a8b8df/3.2/alpine/Dockerfile)
|
|
and scanned image configuration retain the non-root `haproxy` user,
|
|
`/usr/local/etc/haproxy/haproxy.cfg`, entrypoint and graceful-stop signal.
|
|
The [upstream changelog](https://www.haproxy.org/download/3.2/src/CHANGELOG)
|
|
includes HTTP parsing, TLS and memory-safety fixes in 3.2.22/3.2.23.
|
|
Existing specifications retain their explicit image, including an older pin;
|
|
this source change does not update a running installation.
|
|
|
|
| Candidate | OS | C / H / M / L / Unknown, per architecture | Disposition |
|
|
| --- | --- | --- | --- |
|
|
| HAProxy `3.2.23-alpine` | Alpine 3.24.1 | 0 / 0 / 0 / 0 / 0 | Installer source default updated; binary/runtime checks pending |
|
|
| nginx-unprivileged `1.30.4-alpine` | Alpine 3.24.1 | 0 / 0 / 0 / 0 / 0 | Candidate only; compatibility and website OS upgrade review pending |
|
|
| Caddy `2.11.4-alpine` | Alpine 3.23.5 | 1 / 38 / 41 / 12 / 23 | Not selected; all 39 C/H records have recorded fixes |
|
|
| Node `24-alpine` (24.20.0) | Alpine 3.24.1 | 0 / 6 / 11 / 12 / 0 | Not selected; major change and six fixable HIGH records |
|
|
|
|
Each row was scanned separately for **linux/amd64 and linux/arm64**, with the
|
|
same counts on both. Counts are package-vulnerability records, not distinct
|
|
CVEs or proven exploits. The [machine-readable evidence](runtime-image-candidates-2026-09-08.json)
|
|
contains exact index, platform-manifest, config and report digests, inventory
|
|
counts, scanner bounds and decisions. It is audit data, not an accepted release
|
|
manifest or an installer input.
|
|
|
|
nginx's candidate reference is
|
|
`docker.io/nginxinc/nginx-unprivileged:1.30.4-alpine@sha256:442753882674b49ae2c1de83ed67896131c0777f56df5005e356e62bc3f7e7ce`.
|
|
It inventories 70 Alpine packages including nginx/NJS, uses UID 101 and exposes
|
|
8080. The [upstream stable release](https://nginx.org/en/download.html) and
|
|
[security advisories](https://nginx.org/en/security_advisories.html) include the
|
|
1.30.4 fixes. The publisher retains its
|
|
[unprivileged port and temporary-path contract](https://github.com/nginx/docker-nginx-unprivileged).
|
|
For the website, this changes nginx 1.27.5 to 1.30.4, NJS 0.8.10 to 1.0.1 and
|
|
Alpine 3.21.3 to 3.24.1. These changes are explicit review items; the website
|
|
Dockerfile has not been changed. The GovOPlaN Web image still requires an
|
|
explicit verified `NGINX_IMAGE` build argument.
|
|
|
|
Caddy's candidate reference is
|
|
`docker.io/library/caddy:2.11.4-alpine@sha256:5f5c8640aae01df9654968d946d8f1a56c497f1dd5c5cda4cf95ab7c14d58648`.
|
|
Although this is the current
|
|
[official image line](https://raw.githubusercontent.com/docker-library/official-images/master/library/caddy),
|
|
its inventory still includes Go 1.26.3, `x/crypto` 0.52.0, `x/net` 0.55.0,
|
|
`x/text` 0.37.0 and gRPC 1.81.0. Recorded fixes include Go 1.26.6,
|
|
`x/crypto` 0.55.0, `x/net` 0.56.0, `x/text` 0.39.0 and gRPC 1.83.1; Alpine
|
|
findings also remain in c-ares, curl/libcurl and OpenSSL. The CRITICAL
|
|
`CVE-2026-56854` concerns `x/crypto/ssh` source-address enforcement. A module
|
|
record alone does not establish that this binary exposes that SSH path; exact
|
|
binary symbol/reachability analysis is still required for a disposition.
|
|
|
|
The [official Node image catalogue](https://raw.githubusercontent.com/docker-library/official-images/master/library/node)
|
|
still maps Node 22 Alpine to 22.23.2 and the previously scanned digest. Node 24's
|
|
candidate is
|
|
`docker.io/library/node:24-alpine@sha256:e67514e5d0f6c46656005e1b693b2ec9d52e80b641307de684d4a015ba7a4eaf`.
|
|
Its HIGH records remain in two OpenSSL packages and npm dependencies
|
|
`brace-expansion`, `ip-address` and `tar`; fixing the earlier critical tar
|
|
record alone is insufficient. The website builder stays on Node 22 pending
|
|
a reviewed build-tool remedy and a final builder scan.
|
|
|
|
## Method, verification and retained evidence
|
|
|
|
The existing Trivy 0.74.0 executable was rehashed against the previously verified
|
|
archive member: `d89bcc6510a267f11b773398cbf1be5520ce39f9e8b6633178c4487f05b7d791`.
|
|
The same schema-2 vulnerability database was used, updated
|
|
`2026-09-07T19:06:01.154199452Z`. No tool installation or database refresh occurred.
|
|
Index bytes matched both the registry digest header and Docker Hub publisher
|
|
metadata; both platform-manifest byte hashes matched the index. All eight
|
|
registry-only scans completed successfully with validated JSON, `--list-all-pkgs`,
|
|
`--scanners vuln`, an eight-minute/2GB image bound, an empty Docker configuration
|
|
and no inherited credentials. Exit zero means execution succeeded. Private
|
|
temporary paths and in-memory artifact cache isolated this follow-up from the
|
|
earlier scanner's artifact cache; its vulnerability database was read only.
|
|
|
|
Raw reports, logs, manifests, publisher metadata and the scanner script are in
|
|
`/home/zemion/.cache/govoplan-runtime-remediation.qfDSWHJh/`:
|
|
|
|
- `summary.json` SHA-256: `0d44390408ab35270e4430516f77bf11aa7877334eff2ef19e11e9a863fe5c56`.
|
|
- `frozen-images.json` SHA-256: `d0cb156f4a88998531ec55ab950067a3f1350ded648f07650c463af101dad467`.
|
|
- `scan_successors.py` SHA-256: `f64c69e06efc2ad7b5a657a25aa73f9ff586e3685737d525456bcecbe3ab5f07`.
|
|
|
|
Local retention is not permanent artifact hosting; preserve this evidence with
|
|
the eventual reviewed release. The JSON evidence records compressed registry
|
|
layer sizes; these are not expanded filesystem limits or final GovOPlaN sizes.
|
|
|
|
Installer regression checks cover the new generated image pin, legacy
|
|
specification fallback, preserved explicit images, generated topology and
|
|
configuration: `python -I -m unittest discover -s tests -p
|
|
test_deployment_installer.py` ran 45 tests successfully with one skip because
|
|
Core was not importable in that isolated test environment. The skipped Core
|
|
startup-configuration integration was subsequently rerun in the shared development
|
|
environment with Core available: all 45 installer tests passed with no skips,
|
|
including generated-environment startup validation. This is configuration
|
|
validation, not execution of the candidate image.
|
|
Both repositories passed `git diff --check`; the audit JSON and all eight
|
|
report hashes were checked against the retained evidence.
|
|
**Docker, Podman and HAProxy executables are unavailable on
|
|
this host**, so no image or HAProxy configuration was executed and no daemon was
|
|
installed. Publisher metadata and installer tests support the scoped source
|
|
patch; they do not establish binary or deployed compatibility.
|
|
|
|
## Gates that remain open
|
|
|
|
- Validate `haproxy -c` on generated local, existing-proxy and managed-ingress
|
|
configurations using the exact pinned image and target architectures. Run
|
|
bounded isolated checks without live mounts, secrets, privilege or external
|
|
network access. Then verify DNS discovery, readiness, forwarded headers,
|
|
replica routing and graceful termination in the intended runtime.
|
|
- Test the nginx candidate with both the website configuration and GovOPlaN
|
|
WebUI entrypoint/proxy configuration, including UID 101, writable temporary
|
|
paths, health paths, cache headers and static catalog bytes. Approve the
|
|
website nginx/NJS/Alpine version changes before changing its Dockerfile.
|
|
- Resolve Caddy, Node build-tool and all unchanged baseline dependencies with
|
|
updated publisher images or narrow reviewed applicability evidence. No
|
|
severity-wide exceptions or custom third-party rebuilds were introduced.
|
|
- Close the original source-built/static inventory gaps. HAProxy's 24-package
|
|
OS inventory still omits the source-built HAProxy executable. Node's npm
|
|
inventory still omits the Node executable/stdlib. Garage, CPython, Redis,
|
|
PostgreSQL and QEMU gaps are unchanged. Alpine 3.24 EOL metadata is still
|
|
missing from this scanner; zero findings is not complete coverage.
|
|
- Scan **final built** API/Web/website layers and the selected managed
|
|
dependencies on both architectures, then perform migration, worker,
|
|
readiness and ingress smoke checks. Record failure and unknown states.
|
|
Secrets, misconfiguration and image signature policy need separate checks.
|
|
- Obtain the website deployment host/operator and rebuild/restart authority,
|
|
preserving the exact immutable catalog/keyring/module-directory bytes and
|
|
verifying fresh public responses after an authorized rollout.
|
|
|
|
No images were built, executed, published or deployed; no running service,
|
|
release tag, signed manifest, CI image input or live infrastructure was changed.
|