advisory-scan: derive the scan windows from a compose diff (--compose-to) #8

Merged
autonomic-bot merged 1 commits from feat/advisory-scan-compose into main 2026-08-11 19:24:47 +00:00
Owner

Typing --from/--to/--image by hand means someone has to remember that the recipe also bumped its redis. That is how sidecar CVEs went uncounted for months. Point this at a PR's compose.yml and it reads the windows off the diff.

advisory-scan.py plausible --compose-to .../raw/branch/upgrade-4.0.0+v3.2.1/compose.yml

  community-edition: v2.0.0 -> v3.2.1
  clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine
  => 6 CVEs   (identical to the hand-specified args)

Three details that decided the design, each found by it being wrong first:

  • Keyed by SERVICE, not image repo. plausible moved plausible/analyticsghcr.io/plausible/community-edition. Keyed by repo, that reads as one image vanishing and an unrelated one appearing — and the app window, the one carrying the critical CVE-2026-8467, is lost entirely. My first cut did exactly that and reported 0.
  • Baseline = the repo's default branch resolved from the API, never assumed to be main, because several coopcloud recipes keep a stale main beside a live master.
  • Image names match sources BOTH ways. An image name is often longer than its source repo (clickhouse/clickhouse-server vs ClickHouse/ClickHouse) and sometimes shorter (redis vs redis/redis). One-directional matching silently dropped the clickhouse window — the scan said 1 instead of 6.

Credentials go in an Authorization header, never the URL: in-URL creds leak into shell history and process lists, and urllib mis-parses a password containing a colon.

--from/--to/--image stay for finer-grained checks — scanning a window that is not a literal compose diff, e.g. "what would the compatibility-safe target fix?".

71 tests (7 new covering the derivation, incl. the changed-repo and templated-tag cases). Regressions unchanged: discourse 140, gitea 2, mailu 2. SPEC updated.

Typing `--from/--to/--image` by hand means someone has to remember that the recipe also bumped its redis. That is how sidecar CVEs went uncounted for months. Point this at a PR's `compose.yml` and it reads the windows off the diff. ``` advisory-scan.py plausible --compose-to .../raw/branch/upgrade-4.0.0+v3.2.1/compose.yml community-edition: v2.0.0 -> v3.2.1 clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine => 6 CVEs (identical to the hand-specified args) ``` **Three details that decided the design, each found by it being wrong first:** - **Keyed by SERVICE, not image repo.** plausible moved `plausible/analytics` → `ghcr.io/plausible/community-edition`. Keyed by repo, that reads as one image vanishing and an unrelated one appearing — and the app window, the one carrying the **critical** `CVE-2026-8467`, is lost entirely. My first cut did exactly that and reported 0. - **Baseline = the repo's default branch resolved from the API**, never assumed to be `main`, because several coopcloud recipes keep a stale `main` beside a live `master`. - **Image names match sources BOTH ways.** An image name is often longer than its source repo (`clickhouse/clickhouse-server` vs `ClickHouse/ClickHouse`) and sometimes shorter (`redis` vs `redis/redis`). One-directional matching silently dropped the clickhouse window — the scan said 1 instead of 6. Credentials go in an `Authorization` header, never the URL: in-URL creds leak into shell history and process lists, and urllib mis-parses a password containing a colon. `--from/--to/--image` stay for finer-grained checks — scanning a window that is not a literal compose diff, e.g. "what would the compatibility-safe target fix?". **71 tests** (7 new covering the derivation, incl. the changed-repo and templated-tag cases). Regressions unchanged: discourse 140, gitea 2, mailu 2. SPEC updated.
autonomic-bot added 1 commit 2026-08-11 19:24:46 +00:00
Typing --from/--to/--image by hand means someone has to remember the recipe also
bumped its redis. That is how sidecar CVEs went uncounted for months. Point this
at a PR's compose.yml and it reads the windows off the diff instead.

  advisory-scan.py plausible --compose-to <.../branch/<pr>/compose.yml>
    -> community-edition: v2.0.0 -> v3.2.1
    -> clickhouse-server: 23.4.2.11-alpine -> 24.12-alpine
    -> 6 CVEs, identical to the hand-specified args

Details that mattered:

- keyed by SERVICE, not image repo. plausible moved plausible/analytics ->
  ghcr.io/plausible/community-edition; keyed by repo that reads as one image
  vanishing and an unrelated one appearing, and the app window - the one carrying
  the critical - is lost entirely.
- the baseline is the repo's DEFAULT BRANCH resolved from the API, never assumed
  to be main, because several recipes keep a stale main beside a live master.
- image names are matched against advisory sources BOTH ways: an image name is
  often longer than its source repo (clickhouse/clickhouse-server vs
  ClickHouse/ClickHouse) and sometimes shorter (redis vs redis/redis). One
  direction silently dropped the clickhouse window.
- credentials go in an Authorization header, never the URL: in-URL creds leak
  into shell history and process lists, and urllib mis-parses a password
  containing a colon.

--from/--to/--image remain for finer-grained checks (scanning a window that is
not a literal compose diff). 71 tests; discourse 140 / gitea 2 / mailu 2
unchanged.
autonomic-bot merged commit 4bad1ea6db into main 2026-08-11 19:24:47 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: recipe-maintainers/cc-ci-orchestrator#8