A Debian security update the image does not have, and no way to notice #155
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Postulo/postulo#155
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What the scan found
Grype 0.115.0, against
postulo:latestas built on the test instance:A Debian security update that exists, is in bookworm, and is not in the image. It was the
only genuinely fixable operating-system finding across both scanners — and Trivy did not
report it as fixable at all, which is a reason to keep running both rather than picking one.
Why it is not there
docker/Dockerfileinstalls what it needs and never upgrades what it inherits:There is no
apt-get upgrade.libpcre2-8-0comes frompython:3.14-slim-bookworm, so theimage carries whatever that base image was built with. When Debian publishes a security
update for a package the base image already has, Postulo's image keeps the old one until the
base image is rebuilt and the build is re-run without a cache.
What this asks for
A decision about how the image gets Debian's security updates, and a way to notice when it
has not.
Worth being careful about
apt-get upgradeis the obvious answer and it costs reproducibility. Two builds of thesame commit, a week apart, produce different images — which is exactly what a release image
should not do. The usual compromises: upgrade and accept it (most projects), pin the base
image by digest and bump it deliberately (reproducible, and now somebody has to bump it), or
upgrade only the packages a scan names.
The base image is where most of this lives. 6 CRITICAL and 76 HIGH from Trivy, and
essentially all of them have no fix in bookworm — the normal state of Debian stable,
where the security team triages a great many as no-DSA. Those are not ignorable by choice;
they are unfixable in place, and the only real lever is which base image is used. Debian 13
(trixie) is out, and
python:3.14-slim-trixiewould reset a large part of that backlog. Thatis a bigger decision than this issue and belongs beside it, not inside it.
The two scanners disagree about severity and both are right. Trivy reported 6 CRITICAL
and 78 HIGH; Grype reported 23 Critical and 88 High over the same image. Trivy prefers the
distribution's rating — Debian's view of how a CVE affects its build — while Grype leans on
the NVD's. Neither number is the number, and any threshold written into a pipeline has to say
which tool and which source it means.
Grype also reported
python 3.14.7 -> 3.15.0a6, which is a binary match fixed only in anunreleased alpha. Worth knowing so it is not mistaken for an action.
Nothing was found that should not be in an image. Trivy's secret and misconfiguration
scanners both returned zero findings: no keys, no tokens, no credentials, and nothing the
misconfiguration rules object to. That is worth recording, because it is the result that gets
forgotten when only the bad news is written down.
apt-get upgradenow runs at build time, in both apt layers — the second one matters,because an image built with
POSTULO_EXTRA_PACKAGESrefreshes the index again and must notend up quietly less patched than one built without plugins.
The reproducibility trade is deliberate and written down. Two builds of the same commit a
week apart are no longer the same image. Pinning the base by digest buys that back and makes
Debian's updates arrive only when somebody remembers to bump the digest — a manual step
nobody performs, which is precisely how this finding got here. Between an image that drifts
towards being patched and one that reliably stays unpatched, this takes the first; a release
is published by digest, so the artefact anybody runs is still named exactly. A test fails if
the base is ever pinned by digest without that decision being revisited.
Order is the whole of whether the upgrade does anything, so four tests read the Dockerfile
and hold it there: before
updateit runs against the stale index that caused this; afterinstallthe packages just installed came from the old one; and in aRUNof its own itbecomes a layer served from cache exactly when the index it needed had changed.
The "way to notice" half is documented rather than automated, because the pipeline that
would run it is #156, and that waits on a runner able to build an image at all (#81).
CONTRIBUTING.mdnow records both scanner invocations, why both are run, why they disagreeabout severity — and why the gate is
--ignore-unfixed/--only-fixedrather than aseverity threshold: a Debian stable base carries dozens of High with no fix, so a pipeline
failing on CRITICAL is red every day for reasons nobody can act on, and is switched off
within a fortnight.
python:3.14-slim-trixieis deliberately not in here, as the issue said it should not be —it is a bigger decision and belongs beside this one.
The wiki gained Hardening → The image and Debian's updates: rebuilding is how you get
patched, a running container never updates itself, and most findings in a Debian base image
have no fix, which is normal rather than alarming.
Shipped in
81d16e6on0.3.0, withmainkept level.