fix(docker): eliminate npm-bundled CVEs from the published image - #10182
Merged
Merged
Conversation
`caf768e3c4` untracked it; the DeepAI merge (44069c5, #9443) re-added it. It is an absolute symlink pointing at one machine's checkout, and AGENTS.md keeps `_tasks/` out of the main repo entirely. While tracked, `check-tracked-artifacts.mjs` fails on pre-commit, so no commit can be made on this branch at all — this restores the precedent fix purely to unblock committing, and is unrelated to the Docker change that follows.
Trivy reported 9 HIGH/MEDIUM CVEs against the npm CLI's own bundled node_modules inside the published image (brace-expansion, ip-address, tar, undici under /usr/local/lib/node_modules/npm/node_modules). The base stage claimed `npm install -g npm@latest` shipped patched copies. It does not: npm@12.0.2 (latest) bundles brace-expansion 5.0.7, ip-address 10.2.0, tar 7.5.19 and undici 6.27.0 — all still vulnerable. No npm release fixes them, so that step was buying zero CVEs. Overlay the patched versions onto npm's bundled tree instead, pinned and semver-compatible with the ranges npm's own tree declares (minimatch -> brace-expansion ^5.0.5, socks -> ip-address ^10.1.1, node-gyp -> tar ^7.5.4 and undici ^6.25.0, so undici stays on 6.x). Removing npm from the runner stages was not viable — the app shells out to npm at runtime (installers/utils.ts::runNpm, system/autoUpdate.ts, system/globalPackagePath.ts, api/system/version) — and the old comment asserting otherwise is corrected.
This was referenced Aug 13, 2026
Closed
Closed
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…gosouzapw#10182) * chore(repo): re-untrack the _tasks self-referential symlink `c1caabe7c5` untracked it; the DeepAI merge (7d85321, diegosouzapw#9443) re-added it. It is an absolute symlink pointing at one machine's checkout, and AGENTS.md keeps `_tasks/` out of the main repo entirely. While tracked, `check-tracked-artifacts.mjs` fails on pre-commit, so no commit can be made on this branch at all — this restores the precedent fix purely to unblock committing, and is unrelated to the Docker change that follows. * fix(docker): eliminate npm-bundled CVEs from the published image Trivy reported 9 HIGH/MEDIUM CVEs against the npm CLI's own bundled node_modules inside the published image (brace-expansion, ip-address, tar, undici under /usr/local/lib/node_modules/npm/node_modules). The base stage claimed `npm install -g npm@latest` shipped patched copies. It does not: npm@12.0.2 (latest) bundles brace-expansion 5.0.7, ip-address 10.2.0, tar 7.5.19 and undici 6.27.0 — all still vulnerable. No npm release fixes them, so that step was buying zero CVEs. Overlay the patched versions onto npm's bundled tree instead, pinned and semver-compatible with the ranges npm's own tree declares (minimatch -> brace-expansion ^5.0.5, socks -> ip-address ^10.1.1, node-gyp -> tar ^7.5.4 and undici ^6.25.0, so undici stays on 6.x). Removing npm from the runner stages was not viable — the app shells out to npm at runtime (installers/utils.ts::runNpm, system/autoUpdate.ts, system/globalPackagePath.ts, api/system/version) — and the old comment asserting otherwise is corrected. --------- Co-authored-by: backryun <bakryun0718@proton.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Clears the 9 Trivy alerts raised against the npm CLI's own bundled
node_modulesinside the published image. These are npm internals, not application dependencies:
usr/local/lib/node_modules/npm/node_modules/brace-expansion/package.jsonusr/local/lib/node_modules/npm/node_modules/ip-address/package.jsonusr/local/lib/node_modules/npm/node_modules/tar/package.jsonusr/local/lib/node_modules/npm/node_modules/undici/package.jsonNo npm release fixes these
The
basestage already rannpm install -g npm@latest, and its comment claimed thatshipped patched copies. That claim was false. Measured directly off the published
tarball of the latest npm (
npm pack npm@12.0.2, 2026-08-12):Every one still vulnerable. So
npm install -g npm@latestwas buying build time andzero CVEs — the alerts could never clear by refreshing npm.
Chosen fix — overlay the patched copies (option B)
The
basestage now installs the fixed versions into a scratch prefix with--install-strategy=nested(so each replacement is self-contained) and copies them overnpm's bundled ones, then smoke-tests the result:
Semver-compatible with the ranges npm's own tree declares —
minimatch → brace-expansion ^5.0.5,socks → ip-address ^10.1.1,node-gyp → tar ^7.5.4andnode-gyp → undici ^6.25.0. That last one is why undici stays on the 6.x line: the currentundici@8.10.0would fall outside node-gyp's range, and node-gyp is what the
builderstage uses tocompile better-sqlite3. The loop
test -ds each target first, so a future npm layoutchange fails the build loudly instead of silently skipping the patch.
Alternative discarded — deleting npm from the runner stages (option A)
Rejected on evidence. The old comment asserted "npm is not invoked at runtime in the
runner stages"; that is wrong. The application shells out to npm at runtime in four
places:
src/lib/services/installers/utils.ts::runNpm— embedded services (bifrost, ninerouter, mux, dario) install/update/version-checksrc/lib/system/globalPackagePath.ts—npm root -gsrc/lib/system/autoUpdate.ts— thenpmauto-update channelsrc/app/api/system/version/route.ts— version/update endpointsRemoving npm would silently break embedded services and auto-update inside Docker.
runner-cli(npm install -g @openai/codex @anthropic-ai/claude-code droid openclaw) wouldbreak at build time as well. The false comment is corrected in this PR.
.trivyignore(option C) — not usedNo suppression added. This is a real fix;
.trivyignorestays empty, per its own headerpolicy (prefer fixing over suppressing).
Validation
I could not run
docker build— this sandbox has no Docker daemon (dial unix /var/run/docker.sock: no such file), sodocker build --checkis unavailable too. Whatwas validated for real instead:
npm pack npm@12.0.2+ reading the bundledpackage.jsons produced the four vulnerable versions quoted above.5.0.7 → 5.0.9,10.2.0 → 10.5.0,7.5.19 → 7.5.22,6.27.0 → 6.28.0.npm --version→12.0.2;npm pack npm@12.0.2 --dry-run(exercises pacote + tar) succeeded;npm view tar version(registry round-trip) returned7.5.22;minimatch,socks, andnode-gypall resolve the replaced packages (node-gyp tar 7.5.22 | undici 6.28.0).RUNblock was extracted with Docker's line-continuation joining applied and passedbash -n.tests/unit/dockerfile-npm-bundled-cve-patch.test.ts, 5 tests, all passing. Mutation-checked: reverting the pin tobrace-expansion@5.0.7makes it fail.The remaining end-to-end proof is a clean Trivy scan on the next published image.
Note on the second commit
chore(repo): re-untrack the _tasks self-referential symlinkis not part of the fix._tasksis an absolute symlink into one machine's checkout;caf768e3c4untracked it andthe DeepAI merge (
44069c5f54, #9443) re-added it. While it is tracked,scripts/check/check-tracked-artifacts.mjsfails on every pre-commit on this branch,so nothing can be committed at all. Restoring the precedent fix was the only way to commit
without bypassing the Husky hook (Hard Rule #10). Drop that commit if it is being handled
elsewhere.