Skip to content

deps(v2): consolidate dependency updates and security fixes - #382

Merged
pacphi merged 4 commits into
v2from
chore/deps-consolidate-v2-audit
Oct 23, 2026
Merged

pacphi merged 4 commits into
v2from
chore/deps-consolidate-v2-audit

Conversation

@pacphi

@pacphi pacphi commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Dependency and security pass for the v2 line (Ubuntu 26.04 base), per SECURITY.md "Supported Versions": in-major dependency fixes, toolchain patches only, a dependency audit in the branch's CI, and the branch-local renovate.json.

Superseded PRs

Bot PRs
Dependabot none open against v2
Renovate none open against v2

What changed

1. deps(v2): npm lockfile v2/docker/lib/extensions/vf-management-api/resources/package-lock.json

This is the only committed package-lock.json on the branch.

Package Before After Why
fastify (direct, ^5.8.5 → ^5.12.7) 5.8.5 5.12.7 7 GHSAs, <=5.12.4 (GHSA-w2qp-rph6-63g4, -3m5p-2c4r-xxw2, -4mh8-r7rc-xpvc, -667r-xxjv-c9mm, -p68q-wchp-6fh7, -hwr6-493r-vm6h, -9q9j-q6p8-xq58)
find-my-way 9.4.0 9.10.0 GHSA-c96f-x56v-gq3h (<=9.6.0)
fast-uri 3.1.0 3.1.9 (under ajv) / 4.2.3 (fastify 5.12) 9 GHSAs, 3.0.0 - 3.1.7
ws 8.19.0 8.22.0 GHSA-58qx-3vcg-4xpx, GHSA-96hv-2xvq-fx4p (8.0.0 - 8.20.1)
brace-expansion 5.0.5 5.0.12 7 GHSAs, 3.0.0 - 5.0.11
minimatch (existing ^10.2.1 override) 10.2.4 10.2.6 in-range refresh
fast-copy 3.0.2 3.1.0 GHSA-jggr-w7fw-pc2j (moderate)

Method: raise the fastify floor, then npm update --package-lock-only --ignore-scripts --before=2026-10-20T17:15:00Z (an in-range refresh with a 3-day cutoff). fastify 5.12's own ranges also move some transitive packages up a major: fast-json-stringify ^7, fast-uri ^4, cookie ^2 and set-cookie-parser ^3 (via light-my-request 6.8). These follow from fastify's declared dependencies. No override forces them.

2. deps(v2): Docker image inputs (v2/Dockerfile)

Input Before After Published Why
YQ_VERSION 4.53.2 4.54.1 2026-09-29 4.53.2 is built with Go 1.26.2. Trivy flags its stdlib: CVE-2026-33811, -33814, -39820, -39836 and -42499 (high), plus -39823, -39825 and -39826. 4.54.1 is built with Go 1.27.1.
GH_VERSION 2.90.0 2.102.0 2026-09-30 The same Go 1.26.2 stdlib CVEs. Also fixes GHSA-8xvp-7hj6-mcj9 (high, <=2.92.0), three low GHSAs (<2.97.0) and in-toto GHSA-pmwq-pjrm-6p5r.

ubuntu:26.04 (both stages) is unchanged. CI already builds with pull: true and no-cache: true, so each build takes the current 26.04 point release, which is 26.04.1 today.

3. ci(v2): npm audit gate

The real v2 pipeline is ci-v2.yml on main, called from this branch's shim. It runs a Trivy image scan, which is not blocking, and no dependency audit. This PR adds a branch-local npm-audit job to the shim (.github/workflows/ci.yml), so main doesn't change. The job runs .github/scripts/v2/npm-audit.sh, which:

  • runs npm audit --json --package-lock-only on every committed package-lock.json and fails on any high or critical advisory that v2/audit-ignore doesn't except for that lockfile, which is the same threshold as --audit-level=high;
  • fails closed when npm returns an error body instead of a report (tested with npm_config_registry=http://127.0.0.1:1, which exits 1);
  • fails on an exception that no longer matches anything, so stale ignores get removed.

Exceptions use the same layout as v3's v3/audit-ignore: a v2/audit-ignore file with a justification for each entry.

4. chore(v2): renovate.json

This is the minimal branch-local file needed before main sets useBaseBranchConfig: "merge". It is formatted with the repo's .prettierrc and passes renovate-config-validator --strict on both renovate 37.440.7 and 44.181.0.

Ignores

Advisory Path Why it can't be fixed now Reachability Exit condition
GHSA-83w8-p2f5-377r (high), @fastify/static route-guard bypass via ../%2E%2E, first patched in 10.1.1 @fastify/swagger-ui@3.1.0 > @fastify/static@7.0.4 swagger-ui 3.x pins @fastify/static ^7.0.0, and 7.x has no fix. The fix needs swagger-ui 6.1.2 and static 10, both majors. swagger-ui serves only its own bundled assets under /docs. It sets no allowedPath, and there are no route-scoped guards: auth is a global onRequest hook in server.js. The server also can't start with these dependencies (see the pre-existing issues below). Take the fastify-5 plugin majors (see the deferred majors), then delete the entry. The script fails on the stale entry, so it can't be forgotten.

The sibling advisory GHSA-8pvw-jcv7-9cmj (moderate, allowedPath bypass, fixed in 10.1.2) is below the audit level, and this app doesn't use allowedPath.

Deferred majors

Major Breaking changes Fixes an advisory? Likely code impact here
@fastify/swagger-ui 3 → ≥6.1.2, with the other fastify-5 plugin majors: @fastify/cors 9 → ≥10, @fastify/rate-limit 9 → ≥10, @fastify/swagger 8 → 9, @fastify/websocket 10 → 11 These are the first majors built for fastify 5: their fastify-plugin goes from ^4 to ^5, and the registration-time check moves from 4.x to 5.x. swagger-ui 5 also supports fastify 5 but still uses @fastify/static below 10, so 6.1.2 (@fastify/static ^10.1.0) is needed. I haven't reviewed each plugin's changelog for API changes. Yes: GHSA-83w8-p2f5-377r (high) and GHSA-8pvw-jcv7-9cmj (moderate), through @fastify/static 10. Needed for the server to run at all (see below). Touches the plugin registration in server.js and the websocket routes.
uuid 9 → 11.1.1 (first patched; latest is 14) Several majors (10, 11). 11.1.1 is ESM with a CJS build (main: ./dist/cjs/index.js), so require('uuid') still resolves. Yes: GHSA-w5hq-g745-h8pq (moderate; buffer bounds check in v3/v5/v6 when the caller supplies buf) Low. utils/comfyui-manager.js only calls v4() without buf, so the vulnerable path isn't reached.
node:20-slim → 22/24 in vf-zai-service/resources/Dockerfile Node 20 reached end of life on 2026-04-30. Indirectly (EOL runtime) This Dockerfile isn't built by CI. Its COPY claude-zai/wrapper/ path doesn't match the tree, so I couldn't verify it builds.

Release-age gate (3 days)

lock-age.sh --local origin/v2 .: 1 changed lockfile, 43 new entries, 0 UNDER, 0 UNKNOWN (cutoff 2026-10-20T17:19Z). The youngest new entries are fast-uri 3.1.9 and 4.2.3 at 3.7 days and fast-json-stringify 7.1.2 at 4.0 days. yq 4.54.1 is 24 days old and gh 2.102.0 is 23 days old. No release-age exceptions. I deliberately didn't take gh 2.102.1 (Go 1.27.3, published 2026-10-20T19:35Z, under 3 days old): it isn't itself a first-patched release in GHSA or OSV.

Audit counts

Gate Before After
npm audit --audit-level=high (vf-management-api) 9 (6 high, 3 moderate), fails 3 (1 high excepted, 2 moderate), passes via npm-audit.sh
Trivy image scan (ci-v2.yml on main, not blocking) Code-scanning alerts on v2 (May run): yq and gh with Go 1.26.2 stdlib (5 high, 3 medium each), gh in-toto, pebble and sed yq and gh now Go 1.27.1. See the CI results below.

Pre-existing issues (reported, not fixed: each needs a major or an owner decision)

  • vf-management-api can't start. fastify is ^5, but every @fastify/* plugin is a fastify-4 major. Reproduced on both the old and new lockfiles with npm ci --ignore-scripts and then f.register(require(p)); f.ready(). Every plugin fails with FST_ERR_PLUGIN_VERSION_MISMATCH ("expected '4.x' fastify version"). This dates from the Dependabot fastify bump; see the deferred majors.
  • The lockfile isn't what the extension installs. install.sh copies the resources, then runs npm install express cors helmet pm2 pino pino-pretty uuid. That is a different dependency set, resolved at latest at runtime, rather than npm ci.
  • Six package.json files have no lockfile, so they can't be audited or age-gated: vf-comfyui, vf-jupyter-notebooks, vf-playwright-mcp and vf-web-summary mcp-servers, vf-zai-service wrapper, vf-import-to-ontology, and e2b/template. Generating lockfiles would change runtime install behaviour, so that's left to the owner.
  • Unpinned image inputs: curl https://mise.run | sh, curl https://claude.ai/install.sh | bash, and (vf-zai-service) npm install -g @anthropic-ai/claude-code.
  • yq 4.54.1 is the newest yq. It's built with Go 1.27.1, which OSV lists as affected by GO-2026-6599…6617 (fixed in 1.27.2) and GO-2026-6809 (fixed in 1.27.3). No yq release with a newer Go exists yet. gh 2.102.1 (Go 1.27.3) passes the age gate after 2026-10-23T19:35Z.

Verification

$ .github/scripts/v2/npm-audit.sh                      # HEAD
== npm audit --audit-level=high: v2/docker/lib/extensions/vf-management-api/resources
   counts: critical=0 high=1 moderate=2 low=0 total=3
   ignored  GHSA-83w8-p2f5-377r @fastify/static (high): ...
npm audit: no unignored high or critical advisories      # exit 0
$ (same script on the old lockfile)                     # exit 1, 20 unignored high GHSAs
$ npm_config_registry=http://127.0.0.1:1 .github/scripts/v2/npm-audit.sh   # exit 1, fails closed
$ shellcheck .github/scripts/v2/npm-audit.sh            # clean, with the repo's .shellcheckrc (enable=all)
$ yamllint -c .yamllint.yml .github/workflows/ci.yml && actionlint .github/workflows/ci.yml   # clean
$ npx prettier@3 --check renovate.json .../package.json # clean
$ renovate-config-validator --strict renovate.json      # Config validated successfully
$ lock-age.sh --local origin/v2 .                       # 43 new, 0 UNDER, 0 UNKNOWN

CI (run 39995223099, head 43e05c0, using main's reusable workflows after #378, e.g. actions/checkout@v7.0.1)

All checks pass: Build v2 Docker Image, Generate Test Matrix, Security Scan, Test v2 on Docker, Test v2 on Fly.io, Test v2 on DevPod K8s, CI v2 Required Checks, CI v2 Status, Trivy, and npm audit (high). Mark as Promotion Candidate is skipped because it only runs on main pushes. The last v2 run before this PR (2026-05-14, run 25833797859) was also green, so nothing here is a pre-existing failure.

The empty commit ci(v2): re-run CI on main's updated reusable workflows (#378) only retriggers CI. The first run started 18 s before #378 merged, so I cancelled it.

The Trivy results on this PR are informational, since Trivy isn't blocking in ci-v2.yml. The Go 1.26.2 findings on yq and gh are gone. The newer Go 1.27.1 findings remain: CVE-2026-111943, -78667, -78669 and -97031 (high), fixed in Go 1.27.2/1.27.3 and x/net 0.60.0. They affect yq, gh and /usr/bin/pebble (from the base layer).

  • gh 2.102.1 (Go 1.27.3, x/net 0.60.0) clears every gh finding. It passes the 3-day gate at 2026-10-23T19:35:51Z, so it's a one-line follow-up.
  • There's no yq release with Go ≥ 1.27.2 yet.

🤖 Generated with Claude Code

…d gh in the image

vf-management-api (the v2 line's only package-lock.json):
- fastify ^5.8.5 -> ^5.12.7 (locked 5.12.7); fixes 7 fastify GHSAs.
- In-range lock refresh, cut off at 2026-10-20T17:15Z (3-day release age):
  find-my-way 9.4.0 -> 9.10.0, fast-uri 3.1.0 -> 3.1.9 (ajv) / 4.2.3 (fastify 5.12),
  ws 8.19.0 -> 8.22.0, brace-expansion 5.0.5 -> 5.0.12, minimatch 10.2.4 -> 10.2.6,
  fast-copy 3.0.2 -> 3.1.0.
- npm audit: 9 (6 high, 3 moderate) -> 3 (1 high, 2 moderate); the remaining high
  (@fastify/static via @fastify/swagger-ui 3) needs majors and is excepted in v2/audit-ignore.

v2/Dockerfile:
- yq 4.53.2 -> 4.54.1 and gh 2.90.0 -> 2.102.0 (same majors, both >= 3 days old). Both
  were built with Go 1.26.2, which Trivy flags (CVE-2026-33811/-33814/-39820/-39836/-42499
  high); gh 2.102.0 also clears GHSA-8xvp-7hj6-mcj9 (high, < 2.93.0) and in-toto
  GHSA-pmwq-pjrm-6p5r.
Adds an npm-audit job to the v2 CI shim. It runs .github/scripts/v2/npm-audit.sh, which
runs `npm audit --audit-level=high` on every committed package-lock.json and fails on any
high or critical advisory not excepted in v2/audit-ignore. It fails closed when npm audit
returns an error body (registry timeout) and flags exceptions that no longer match.

The centralized ci-v2.yml on main is unchanged; its Trivy image scan still runs.
main's renovate.json will set useBaseBranchConfig: "merge", which needs a config file on every base branch. Shared policy stays on main.
@pacphi
pacphi merged commit b528a79 into v2 Oct 23, 2026
11 checks passed
@pacphi
pacphi deleted the chore/deps-consolidate-v2-audit branch October 23, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant