chore(deps): durable qs override — close the per-regen audit re-float loop (queue #94)#103
Conversation
…durable GHSA-q8mj-m7cp-5q26 curation (queue #94) Stryker's transitive typed-rest-client@2.3.1 exact-pins vulnerable qs@6.15.1 (GHSA-q8mj-m7cp-5q26 DoS). A lockfile-only pin does not survive clean regens — applied and lost twice before. This adds a regen-invariant overrides block forcing qs>=6.15.2 within the typed-rest-client subtree, so curation holds across any future npm install from scratch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying fs-packages with
|
| Latest commit: |
8829d12
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://fb7b550c.fs-packages.pages.dev |
| Branch Preview URL: | https://medic-queue-94-durable-qs-ov.fs-packages.pages.dev |
jasperboerhof
left a comment
There was a problem hiding this comment.
Approved — reviewed, no blockers.
…e-qs-override # Conflicts: # package-lock.json
|
Rebased onto current The manual rebase push dismissed the prior approval — re-approval needed before merge. The other five PRs in this wave (#94, #102, #77, #99, #101) are merged; |
|
Branch freshened to current |
Goosterhof
left a comment
There was a problem hiding this comment.
No blockers, no concerns, one nit. This is the right shape of fix for the failure mode it documents.
Praise
The diagnosis is correct and the fix matches it. A lockfile entry is a resolution snapshot, not a constraint — any clean regen re-floats the tree, which is exactly why the lockfile-only approach lost the curation twice (PR #100, then PR #102's vue regen). A scoped overrides block in package.json:40-44 is the regen-invariant form: it constrains typed-rest-client's qs to ^6.15.2 regardless of which typed-rest-client version floats up. Verified against origin/main:package.json — no overrides block there, engines follows devDependencies directly, so this genuinely closes the per-regen re-float loop rather than re-applying a transient patch.
The durability evidence is the load-bearing part, not the five-line diff. Two rm -rf node_modules package-lock.json && npm install && npm audit cycles landing typed-rest-client@2.3.1 with qs@6.15.2 and 0 vulnerabilities is the right proof — it demonstrates the override holds at the exact parent version (2.3.1) that previously exact-pinned the vulnerable qs@6.15.1, which is the only version that matters here. The lockfile-only approach structurally could not produce that proof.
Nit
The scoped-nested override form ("typed-rest-client": { "qs": "^6.15.2" }) is correct and minimal, but it's silent about intent — six months from now a typed-rest-client bump that re-vendors qs cleanly leaves a dangling override with no breadcrumb. The PR body carries the GHSA reference and the rationale; the manifest does not. Not blocking — npm overrides doesn't take comments and a parallel // _comment key would trip oxfmt/lint. Worth a one-line note in enforcement/queue.md #94's closeout so the override has a documented expiry condition (drop it once typed-rest-client no longer pins a vulnerable qs range).
Scope is honest: root package.json override + package-lock.json regen only, no range widening, no unrelated bumps. The lint:pkg publint baseline is correctly declared pre-existing and out of scope (PR #101). COMMENT — merge-worthy as-is.
PR Reviewer · claimed
|
PR Reviewer · 8/10 · PASS
Findings
Actionmerge-ready |
jasperboerhof
left a comment
There was a problem hiding this comment.
Auto-approved by /review-open-prs — review verdict is PASS. See the verdict comment for the per-reviewer breakdown.
Summary
Closes enforcement queue #94. Makes the
qs/typed-rest-clientaudit curation durable by replacing the per-regen lockfile patch with a regen-invariantoverridesblock in rootpackage.json.The problem — a lockfile pin is not a constraint
Stryker's transitive
typed-rest-client@2.3.1exact-pins vulnerableqs@6.15.1(GHSA-q8mj-m7cp-5q26, moderate DoS —qs.stringifycrashes on null/undefined entries in comma-format arrays).typed-rest-client@2.3.0declaresqs@^6.14.1→ resolves to patched6.15.2.The fix has been applied lockfile-only three times and lost twice, because a lockfile entry is not a constraint — any clean regen re-floats the tree:
npm audit fix— held until next regenmainitself was onenpm installaway from a red audit. Verified directly: a clean regen on currentmainre-floatstyped-rest-clientto>=2.3.1and reintroducesqs@6.15.1→The fix — regen-invariant override
Scoped to the offending subtree, version-agnostic on the parent — forces
qsto the patched line regardless of whichtyped-rest-clientversion floats. (oxfmt reordersoverridesaboveengines; left as formatted.) The nested form took effect on first clean install — no top-level fallback needed.After the override, the lockfile resolves
typed-rest-client@2.3.1(the version that exact-pins vulnerable qs) withqs@6.15.2— proving the override holds even at the parent version that previously poisoned the tree.Durability proof — TWO clean-from-scratch regens
Each is
rm -rf node_modules package-lock.json && npm install && npm audit:npm auditNo manual
npm audit fixbetween regens — which the lockfile-only approach structurally could not achieve.qs grep (post-fix): single hoisted copy
node_modules/qs@6.15.2, no nested vulnerable copy undertyped-rest-client.Gate matrix
npm auditnpm run format:checknpm run lintnpm run buildnpm run typechecknpm run test:coveragenpm run lint:pkgAll 11
@script-development/fs-*workspace packages still link topackages/*(link: true), no nested registry copies. The largepackage-lock.jsondiff is benign full-tree reordering from the clean regen.Scope
Root
package.json(overrides block) +package-lock.jsononly. No other manifest edits, no range widening, no version bumps beyond the qs override.🤖 Generated with Claude Code