diff --git a/.claude/skills/prisma-taurus/SKILL.md b/.claude/skills/prisma-taurus/SKILL.md index 473b31e36..f93348e57 100644 --- a/.claude/skills/prisma-taurus/SKILL.md +++ b/.claude/skills/prisma-taurus/SKILL.md @@ -74,8 +74,9 @@ These jars (netty, log4j, tika, batik, xstream, jackson, logback, pebble, dnsjav | `/root/.bzt/newman/node_modules/` | npm override | Dockerfile newman `package.json` printf block | | `/root/.bzt/selenium-taurus/mocha/node_modules/` | npm override | Dockerfile mocha `package.json` printf block | | `/root/.bzt/selenium-taurus/*/node_modules/` | npm direct package | `bzt/modules/javascript.py` PACKAGE_NAME constant | +| `/usr/lib/node_modules/npm/node_modules/` | npm-internal bundled dep | bump global npm (`npm i -g`); if the latest npm still bundles the vulnerable version → **monitor**. There is **no clean in-place override** (see "npm-internal bundled deps" section) | | `/usr/local/rbenv/` or `/usr/local/lib/ruby/` | Ruby gem | Dockerfile `gem install -v ` + default-gem/cache cleanup (see Ruby gems section) | -| empty path or OS path (`/usr/lib/`, `/lib/`) | OS package | Dockerfile `apt-get install --only-upgrade` | +| empty path or OS path (`/usr/lib/`, `/lib/`) — **excluding** `/usr/lib/node_modules/npm/node_modules/` (npm-internal, see row above) | OS package | Dockerfile `apt-get install --only-upgrade` | | Python pkg, `Path` under `/usr/local/lib/python3.x/...` | Python package | `requirements.txt` (feeds the wheel's `install_requires`) or a dedicated Dockerfile `pip install` step — **classify into 5 cases**, see Python section | | Python pkg, `Path` under `/usr/lib/python3/dist-packages/...` | distro Python (apt) | Dockerfile `apt-get install --only-upgrade`/`apt-get purge` (NOT `requirements.txt`) | @@ -277,6 +278,23 @@ Find the `printf` block that seeds `/root/.bzt/selenium-taurus/mocha/package.jso --- +#### npm-internal bundled deps (Dockerfile) — `/usr/lib/node_modules/npm/node_modules/` + +Deps bundled **inside the global `npm` CLI itself** (`undici`, `glob`, `cross-spawn`, …), installed by `npm i -g npm@N`. **The only safe fix is to bump npm; otherwise monitor.** + +1. **Bump npm.** Check what the latest npm bundles (it's pinned in npm's own lockfile): + ```bash + curl -s https://raw.githubusercontent.com/npm/cli/v/package-lock.json \ + | python3 -c "import json,sys;d=json.load(sys.stdin);print(d['packages'].get('node_modules/',{}).get('version'))" + ``` + If the latest npm bundles the fixed version → the existing `npm i -g npm@11` clears it on rebuild. +2. **If the latest npm still bundles the vulnerable version → MONITOR.** Do **not** try to patch it in place: + - `cd /usr/lib/node_modules/npm && npm install @` **does not work** — it makes npm re-resolve its *own* `package.json`, which references unpublished workspace deps (`@npmcli/docs`), and the build fails with a registry `404`. **Verified failing** in taurus build #571 and taurus-cloud `MOB-51270` build #1. + - The only mechanism that would replace the dep is copying a temp-installed folder over npm's bundled one — that's the **brittle "manual unpack"** the cross-spawn lesson (commit #4) warns against. Don't. + - So the correct action is monitor: re-check each run; the fix lands automatically once an npm release bundles the patched dep and `npm i -g npm@11` picks it up. + +--- + #### .NET SDK bump (Dockerfile) When a CVE is in a .NET SDK component: diff --git a/.claude/skills/prisma-taurus/vulnerability_history.md b/.claude/skills/prisma-taurus/vulnerability_history.md index 2c4e566bc..f964e0560 100644 --- a/.claude/skills/prisma-taurus/vulnerability_history.md +++ b/.claude/skills/prisma-taurus/vulnerability_history.md @@ -349,8 +349,12 @@ The first attempt removed net-imap 0.5.8's gemspec + lib dir but **not** its cac ### When cross-spawn / npm internals are flagged - Check if upgrading npm globally (`npm i -g npm@XX`) resolves it — this is always preferable to manually unpacking packages into npm's internal node_modules. -- **But first verify the bundled version actually advanced.** npm bundles its deps (`cross-spawn`, `glob`, `undici`, …); a version bump only helps if the *latest* npm bundles the fixed dep. Confirm the bundled version at the npm/cli tag before deciding — it's pinned in npm's own lockfile: `curl -s https://raw.githubusercontent.com/npm/cli/v/package-lock.json | python3 -c "import json,sys; d=json.load(sys.stdin); print([v['version'] for k,v in d['packages'].items() if k.endswith('node_modules/')])"`. If the latest npm still ships the vulnerable version, the CVE is **not fixable yet** — leave it as monitor; do **not** hand-unpack into npm internals (that's the brittle cross-spawn mistake from commit #4). Removal/monitor condition: re-check on each run; fix lands automatically once `npm i -g npm@11` picks up an npm release bundling the patched dep. - - *Worked example (2026-06-25, scan #155):* undici 6.26.0 in `/usr/lib/node_modules/npm/node_modules/undici` (CVE-2026-12151 high + 3) — fix is undici 6.27.0, but npm 11.17.0 (latest) still bundled 6.26.0, so it was left as monitor rather than patched in place. +- **But first verify the bundled version actually advanced.** npm bundles its deps (`cross-spawn`, `glob`, `undici`, …); a version bump only helps if the *latest* npm bundles the fixed dep. Confirm the bundled version at the npm/cli tag before deciding — it's pinned in npm's own lockfile: `curl -s https://raw.githubusercontent.com/npm/cli/v/package-lock.json | python3 -c "import json,sys; d=json.load(sys.stdin); print([v['version'] for k,v in d['packages'].items() if k.endswith('node_modules/')])"`. If the latest npm still ships the vulnerable version, the CVE is **not fixable yet** — leave it as monitor. Do **not** try to patch it in place: + - **`cd /usr/lib/node_modules/npm && npm install @` does NOT work.** Running `npm install` inside npm's own directory makes npm re-resolve npm's *own* `package.json`, which references unpublished internal workspace deps (e.g. `@npmcli/docs@^1.0.0`) → the install dies with a registry **`404 Not Found`** and the Docker build fails. **Verified failing twice (2026-06-26):** taurus `taurus-branch-builder` build #571 and taurus-cloud `CRANE-TAURUS-CLOUD-CI/MOB-51270-manual-undici-fix` build #1 — identical `@npmcli/docs` 404. + - The only thing that *would* swap the dep is installing it in a temp dir and **copying the folder** over npm's bundled one — but that is the **brittle "manual unpack"** the cross-spawn mistake (commit #4) warns against: path-dependent, no clean removal, fights npm's own tree. Not worth it. + - **Conclusion:** for npm-internal bundled deps there is no clean override — **bump npm or monitor.** (An earlier 2026-06-26 attempt to soften this rule to "allow a guarded `npm install` override" was reverted once both builds above proved the override can't even build. Kept on local branch `prisma-taurus-npm-bundled-deps`, not merged.) + - Removal/monitor condition: re-check on each run; fix lands automatically once `npm i -g npm@11` picks up an npm release bundling the patched dep. + - *Worked example (2026-06-25, scan #155 / 2026-06-26, scan #166):* undici 6.26.0 in `/usr/lib/node_modules/npm/node_modules/undici` (CVE-2026-12151 + 3 more) — fix is undici 6.27.0, but npm 11.17.0 (latest) still bundles 6.26.0 → **monitor**. ### Verify in the image before opening a PR - A branch *can* be scanned before merge: `taurus-branch-builder` (`run_integration=true`, `push_docker=true`, `public_docker=false`, `PERFORM_PRISMA_SCAN=true`) builds the branch into `us.gcr.io/verdant-bulwark-278/taurus:-`, runs integration, and prints a twistcli scan in the console. Use it to confirm each fix actually landed and the counts dropped **before** creating the PR. (Earlier history wrongly assumed no pre-merge image existed.)