Skip to content

[PD1-80] Refresh dependencies and drop the js-yaml/test-exclude resolutions - #35

Merged
joshuanapoli merged 1 commit into
mainfrom
deps/clear-vulns
Sep 6, 2026
Merged

joshuanapoli merged 1 commit into
mainfrom
deps/clear-vulns

Conversation

@joshuanapoli

Copy link
Copy Markdown
Member

Clears the last open Dependabot alert on this repo and refreshes the transitive tree. The resolutions block is removed — it is no longer load-bearing.

Vulnerability cleared

GHSA-3jxr-9vmj-r5cp (high, dev scope) — brace-expansion 5.0.4 → 5.0.9. The recently merged #32 only fixed the 2.x resolution; the 5.x path via minimatch@10.2.4 was untouched. minimatch asks for ^5.0.2, so this is a plain in-range bump and never needed a resolution.

Why the resolutions can now be removed

Both entries existed to work around the same root cause — Jest's coverage instrumentation:

@jest/transform / babel-jest
  └─ babel-plugin-istanbul
       ├─ test-exclude ^6.0.0
       └─ @istanbuljs/load-nyc-config ─ js-yaml ^3.13.1

babel-plugin-istanbul is a hard dependency of @jest/transform, so it cannot be dropped from the tree — not even by transforming with @swc/jest, which is what we do. When #10 added the overrides, neither pinned range contained a patched version, so forcing a semver-major (js-yaml ^4, test-exclude ^8) was the only option.

That is no longer true. Upstream fixed both inside the pinned ranges:

  • js-yaml backported its fixes to the 3.x line. 3.14.1 carries four advisories (GHSA-5p4m-2wfm-xmqj, GHSA-52cp-r559-cp3m, GHSA-h67p-54hq-rp68, GHSA-mh29-5h37-fv8m); 3.15.2 has none, and it satisfies ^3.13.1.
  • babel-plugin-istanbul moved its pin to test-exclude ^7.0.1, which resolves to a clean 7.0.2.

So re-resolving with no overrides lands on patched versions unaided. I verified the result against the GitHub Advisory Database (js-yaml@3.15.2, test-exclude@7.0.2, glob@10.5.0, brace-expansion@2.1.4, brace-expansion@5.0.9 — all clean) and with yarn npm audit --all --recursive, whose only remaining output is a deprecation notice on glob@10.5.0, not a CVE.

Removing them is also a correctness win, because both overrides were semver-major and therefore unsound in principle. They happened to be safe — I checked the actual call sites: @istanbuljs/load-nyc-config only calls require('js-yaml').load(), which exists in both 3.x and 4.x, and babel-plugin-istanbul only uses new TestExclude() and shouldInstrument(), both unchanged and synchronous in 8.x. But nothing was enforcing that, and CI never exercised it (see below). Dropping the overrides removes a standing risk rather than adding one.

Risks

Low, but this is a large diff, so worth being precise about what actually moves.

  • Runtime surface changes by exactly one in-range minor: axios 1.18.0 → 1.20.0. Every other package reachable from dependencies (commander, follow-redirects, form-data, proxy-from-env, asynckit, combined-stream, mime-types) resolves to the identical version as on main. src/ uses only axios.get with headers/params and response generics; tsc builds clean against the new types.
  • Everything else in the ~2,700-line lockfile diff is dev scope and does not ship in the CLI.
  • The coverage path was previously untested in CI. ci.yml runs yarn test without --coverage, so the instrumentation code that consumes test-exclude and js-yaml never ran there — the old overrides were effectively unverified. I ran yarn test --coverage locally against this branch: instrumentation works and reports 82.14% statements across 4 suites.
  • Tradeoff to be aware of: we now rely on upstream continuing to patch the js-yaml 3.x line rather than pinning ourselves onto 4.x. If 3.x is abandoned, the override may need to come back. Dependabot will tell us.

Verification

Full CI suite locally, plus coverage:

  • yarn install --immutable — clean
  • yarn prettier --check . — clean
  • yarn eslint . — clean
  • yarn test — 25 passed, 4 suites
  • yarn test --coverage — 25 passed, instrumentation exercised
  • yarn build — clean

Deliberately not included

These are behind a major and unrelated to any advisory, so they do not belong in a security-cleanup PR:

Package Current Latest
commander 11.1.0 15.0.0
typescript 5.9.3 7.0.2
@eslint/markdown 7.5.1 8.0.3
globals 16.5.0 17.12.0
@types/node 20.19.43 26.4.1
prettier 3.6.2 (pinned exact) 3.9.6

Worth a separate look: @types/node is pinned to ^20 while CI runs Node 24, so we type-check against an older stdlib than we execute on.

Clears GHSA-3jxr-9vmj-r5cp (high, brace-expansion 5.x) and refreshes the
whole transitive tree within the existing direct-dependency ranges.

The `resolutions` block is no longer needed. It was added in #10 to force
semver-major overrides on two packages that Jest's coverage path pins to
vulnerable ranges:

  babel-plugin-istanbul -> test-exclude ^6.0.0
  babel-plugin-istanbul -> @istanbuljs/load-nyc-config -> js-yaml ^3.13.1

At the time neither range contained a patched version, so the only way out
was to override across a major. Upstream has since fixed that in range:
js-yaml backported the merge-key and prototype-pollution fixes to the 3.x
line (3.15.2 is clean; 3.14.1 carries four advisories), and
babel-plugin-istanbul moved to `test-exclude ^7.0.1`, which resolves to a
clean 7.0.2. Re-resolving without the overrides now lands on patched
versions on its own.

Runtime impact is limited to axios 1.18.0 -> 1.20.0; every other package in
the shipped dependency tree resolves to the same version as before. The rest
of the diff is dev-scope.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@joshuanapoli joshuanapoli changed the title Refresh dependencies and drop the js-yaml/test-exclude resolutions [PD1-80] Refresh dependencies and drop the js-yaml/test-exclude resolutions Sep 6, 2026
@joshuanapoli
joshuanapoli merged commit 8887df5 into main Sep 6, 2026
1 check passed
@joshuanapoli
joshuanapoli deleted the deps/clear-vulns branch September 6, 2026 16:04
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