Skip to content

chore(ci): drop unpinned global install of @nestjs/cli and nx - #60

Merged
karlkeppner1 merged 3 commits into
chains/realio-testnetfrom
chore/remove-unpinned-global-install
Aug 6, 2026
Merged

chore(ci): drop unpinned global install of @nestjs/cli and nx#60
karlkeppner1 merged 3 commits into
chains/realio-testnetfrom
chore/remove-unpinned-global-install

Conversation

@karlkeppner1

@karlkeppner1 karlkeppner1 commented Aug 6, 2026

Copy link
Copy Markdown

Found while auditing the workspace for exposure to the Shai-Hulud npm supply-chain attack (keyv and friends). No compromised packages were found in this repo — the lockfile is clean and so are the running pods.

1. Drop unpinned global install (the original change)

Removes npm i -g @nestjs/cli nx from the common-test workflow.

  • Neither binary is ever invoked. The job's only commands are npm ci and npm audit.
  • Neither package is a dependency. nx, @nestjs/cli, @nestjs/core are all absent from package.json. No nx.json, no nest-cli.json.
  • No lifecycle scripts need them on PATH.
  • It was unpinned and ran before npm ci, so it resolved both packages plus their full transitive trees fresh from the registry on every PR — outside the lockfile and outside the min-release-age=3 gate added in chore: gate npm installs by 3-day minimum release age #58.

2. Clear the three critical advisories

npm audit --audit-level=critical was already failing on chains/realio-testnet before this PR. I verified by auditing the unmodified base branch: 3 critical / 26 high / 60 total. It is unrelated to the workflow change — npm audit reads the local tree from the lockfile and never sees globally installed packages. It surfaced because the advisory database moved since the base last ran CI on 2026-06-30.

package advisory fix
tar <=7.5.20 GHSA-r292-9mhp-454m + others override ^7.5.22
shell-quote <=1.8.4 command injection override ^1.10.0
next 15.5.0 GHSA-9qr9-h5gf-34mp RCE in React flight protocol ^15.5.22

On next — no major upgrade needed

npm reports fixAvailable.isSemVerMajor: true for next, which suggests 16.x. That is an aggregate over every advisory filed against the package and is misleading here. The critical one is narrow — >=15.5.0-canary.0 <15.5.7 — and the lockfile sat at 15.5.0, just inside it. 15.5.22 clears every advisory listed (highest floor is <15.5.21) and already satisfied the declared ^15.2.1, so this is a lockfile bump within the existing range. package.json is raised to ^15.5.22 only to record the floor explicitly.

tar and shell-quote are both transitive, so overrides resolves them without touching direct dependencies.

Result

npm audit --audit-level=critical exits 0. Verified locally against the regenerated lockfile.

Follow-up (not in this PR)

min-release-age requires npm >= 11.10.0. This workflow pins node-version: 23, which ships npm 10.9.2 — so the .npmrc gate from #58 is currently inert in CI. It does apply in the Docker build, which upgrades npm first. Worth a separate PR to bump the runner's npm.

karlkeppner1 and others added 3 commits August 6, 2026 09:33
The common-test job installed @nestjs/cli and nx globally at latest before
running npm ci, but neither binary is ever invoked. The job only runs
npm ci and npm audit. Neither package is in package.json, there is no
nx.json or nest-cli.json, and there are no install lifecycle scripts that
could need them on PATH.

Because it ran before npm ci and was unversioned, the step resolved both
packages plus their full transitive trees fresh from the registry on every
PR, outside any lockfile or the min-release-age gate in .npmrc.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Clears 2 of the 3 criticals that fail npm audit --audit-level=critical on
the base branch:

  tar <=7.5.20        GHSA-r292-9mhp-454m and others -> ^7.5.22
  shell-quote <=1.8.4 command injection               -> ^1.10.0

Both are transitive, so overrides resolve them without touching direct
dependencies.

The third critical, next (^15.2.1, vulnerable through 16.3.0-preview.10),
is a direct dependency whose only fix is a semver-major upgrade to 16.x.
That is a framework migration needing its own PR and QA, so it is left
alone here and this job will still report the single remaining critical.

These failures predate the workflow change in this PR and are unrelated to
it -- npm audit reads the local tree from the lockfile and never sees
globally installed packages.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Corrects the previous commit's claim that this needed a semver-major
upgrade to 16.x. It does not.

npm reported fixAvailable.isSemVerMajor for `next`, but that is an
aggregate over every advisory filed against the package. The critical one
is narrow:

  GHSA-9qr9-h5gf-34mp  RCE in React flight protocol
  vulnerable: >=15.5.0-canary.0 <15.5.7

The lockfile pinned 15.5.0, squarely inside that window. 15.5.22 is the
current 15.x and clears every advisory listed for next -- the highest
floor among them is <15.5.21. No major upgrade, no framework migration.

15.5.22 already satisfied the declared ^15.2.1 range, so this is a
lockfile bump; package.json is raised to ^15.5.22 only to record the
security floor explicitly.

npm audit --audit-level=critical now exits 0.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@karlkeppner1
karlkeppner1 merged commit dd94086 into chains/realio-testnet Aug 6, 2026
1 check passed
@karlkeppner1
karlkeppner1 deleted the chore/remove-unpinned-global-install branch August 6, 2026 17:01
karlkeppner1 added a commit that referenced this pull request Aug 7, 2026
The chains/realio-testnet build is currently broken:

  #8 RUN npm i -g npm@latest
  npm error code EBADENGINE
  npm error Required: {"node":"^22.22.2 || ^24.15.0 || >=26.0.0"}
  npm error Actual:   {"npm":"10.9.2","node":"v23.11.1"}

npm@latest resolved to 12.0.2, which dropped node 23 support. The image is
node:23-alpine, and .npmrc sets engine-strict=true, so this is a hard
error rather than a warning. Nothing in the repo changed to cause it --
the registry moved under an unpinned install.

11.19.0 is the newest npm whose engines (^20.17.0 || >=22.9.0) still cover
node 23, and it is >= 11.10.0, so the min-release-age=3 cooldown from #58
continues to apply. That was the entire reason this upgrade step exists.

This is the same unpinned-global-install class of bug that #60 addressed
in the workflow; this Dockerfile line was missed.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
karlkeppner1 added a commit that referenced this pull request Aug 7, 2026
Brings this PR to dependency parity with chains/realio-testnet, where the
same upgrades landed as #61 and soaked.

Dropped two changes from the original commit that moved backwards and
appear unintentional:

  ethereumjs-util          ^7.0.2 -> ^7.1.5  (restored)
  @socialgouv/matomo-next  ^1.2.1 -> ^1.6.1  (restored)

The seven genuine upgrades are unchanged and now match testnet exactly:
@cosmjs/stargate ^0.39.0 and the six @graphql-codegen majors.

Also carries the security fixes that landed on testnet as #60, without
which npm audit --audit-level=critical fails on this base:

  overrides.tar          ^7.5.22   (GHSA-r292-9mhp-454m and others)
  overrides.shell-quote  ^1.10.0   (command injection)
  next                   ^15.5.22  (GHSA-9qr9-h5gf-34mp, RCE)

package.json is now identical to chains/realio-testnet for all ten
entries plus overrides.

Lockfile regenerated on the chains/realio base with npm 11.19.0 so the
min-release-age=3 cooldown in .npmrc applies. Verified:

  npm ci --dry-run under npm 10.9.2 (node 23 in common-test)  exit 0
  npm audit --audit-level=critical                            exit 0
  0 critical / 15 high (was 2 critical / 16 high)
  docker build of the full image, including npm run build:next

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
karlkeppner1 added a commit that referenced this pull request Aug 7, 2026
Without this, merging the dependency changes in this PR would go green on
common-test and then break the mainnet build, because chains/realio still
carries the two unpinned installs that were already fixed on
chains/realio-testnet.

Dockerfile: npm i -g npm@latest -> [email protected]

  npm@latest now resolves to 12.0.2, whose engines are
  ^22.22.2 || ^24.15.0 || >=26.0.0. This image is node:23-alpine and
  .npmrc sets engine-strict=true, so the install is a hard error. This is
  exactly what broke chains/realio-testnet (run 31193609639), fixed there
  by #62. 11.19.0 is the newest npm still covering node 23, and is
  >= 11.10.0 so the min-release-age=3 cooldown keeps applying.

common-test.yaml: drop `npm i -g @nestjs/cli nx`

  Neither binary is ever invoked -- the job only runs npm ci and npm audit.
  Neither package is in package.json, there is no nx.json or nest-cli.json,
  and no install lifecycle scripts need them on PATH. Unpinned and run
  before npm ci, so it resolved both plus their full transitive trees on
  every PR. Same change merged to testnet as #60.

Verified with a full docker build: npm i -g [email protected] succeeds, npm ci
completes, npm run build:next completes, image tags.
npm audit --audit-level=critical exits 0.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
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