chore(deps): pin patched transitive deps via pnpm.overrides #42

Merged
julien merged 1 commits from chore/deps/audit-overrides into main 2026-05-06 21:38:53 +02:00
Owner

Summary

Direct-dep updates from Renovate could not clear the scan gate — 20 vulnerabilities (4 high + 13 moderate + 3 low) lived inside transitive chains pinned by upstream tooling:

  • nx > axios (8× CVEs), nx > yaml, nx > follow-redirects
  • @nx/devkit > minimatch > brace-expansion
  • nestjs-prisma > @angular-devkit/core > ajv
  • @angular/cli > @modelcontextprotocol/sdk > express-rate-limit > ip-address
  • @lhci/cli > tmp

Patched versions exist upstream but the parents pin tighter ranges. Renovate cannot help here — pnpm.overrides with the upper-bound form (pkg@<x.y.z) is the right tool: it forces patched resolutions today and self-expires once a parent legitimately reaches the patched version (the override stops matching).

After overrides: pnpm audit --audit-level=moderate0 vulnerabilities.

Bonus fix

Lint-staged was running prettier on pnpm-lock.yaml because the glob *.yaml matched. Tightened the glob to !(pnpm-lock).{...,yaml} so the lockfile stays under pnpm's own formatting authority.

Test plan

  • scan job goes green on this PR.
  • No regression on check (lint/test/build).
  • On the next deps-bump commit (any future Renovate PR rebased), the local pre-commit hook does not reformat pnpm-lock.yaml.

Out of scope (separate follow-up PRs)

While testing locally, two pre-existing regressions on main surfaced (introduced by recent Renovate major bumps that passed CI through nx affected reporting "nothing affected"):

  • TypeScript 6 (PR #33)tsconfig.lib.jsonTS5101: Option 'baseUrl' is deprecated on every lib build.
  • ESLint 10 (PR #36)@nx/eslint@22.7.1 plugin can't resolve eslint, project graph fails.

Both deserve their own investigation before we move on to phase-2 chantiers.

## Summary Direct-dep updates from Renovate could not clear the `scan` gate — 20 vulnerabilities (4 high + 13 moderate + 3 low) lived inside transitive chains pinned by upstream tooling: - `nx > axios` (8× CVEs), `nx > yaml`, `nx > follow-redirects` - `@nx/devkit > minimatch > brace-expansion` - `nestjs-prisma > @angular-devkit/core > ajv` - `@angular/cli > @modelcontextprotocol/sdk > express-rate-limit > ip-address` - `@lhci/cli > tmp` Patched versions exist upstream but the parents pin tighter ranges. Renovate cannot help here — `pnpm.overrides` with the **upper-bound** form (`pkg@<x.y.z`) is the right tool: it forces patched resolutions today and self-expires once a parent legitimately reaches the patched version (the override stops matching). After overrides: `pnpm audit --audit-level=moderate` → **0 vulnerabilities**. ## Bonus fix Lint-staged was running prettier on `pnpm-lock.yaml` because the glob `*.yaml` matched. Tightened the glob to `!(pnpm-lock).{...,yaml}` so the lockfile stays under pnpm's own formatting authority. ## Test plan - [ ] `scan` job goes green on this PR. - [ ] No regression on `check` (lint/test/build). - [ ] On the next deps-bump commit (any future Renovate PR rebased), the local pre-commit hook does **not** reformat `pnpm-lock.yaml`. ## Out of scope (separate follow-up PRs) While testing locally, two pre-existing regressions on `main` surfaced (introduced by recent Renovate major bumps that passed CI through `nx affected` reporting "nothing affected"): - **TypeScript 6 (PR #33)** — `tsconfig.lib.json` → `TS5101: Option 'baseUrl' is deprecated` on every lib build. - **ESLint 10 (PR #36)** — `@nx/eslint@22.7.1` plugin can't resolve eslint, project graph fails. Both deserve their own investigation before we move on to phase-2 chantiers.
julien added 1 commit 2026-05-06 21:29:35 +02:00
chore(deps): pin patched transitive deps via pnpm.overrides
CI / commits (pull_request) Successful in 2m13s
CI / check (pull_request) Failing after 2m23s
CI / a11y (pull_request) Successful in 1m45s
CI / perf (pull_request) Failing after 2m4s
CI / scan (pull_request) Failing after 7m29s
1edaeb1857
Renovate-driven updates of direct deps could not clear the audit
gate: 20 vulnerabilities (4 high + 13 moderate + 3 low) lived inside
transitive chains pinned by upstream tooling — `nx > axios`,
`nx > yaml`, `nx > follow-redirects`, `@nx/devkit > minimatch >
brace-expansion`, `nestjs-prisma > @angular-devkit/core > ajv`,
`@angular/cli > @modelcontextprotocol/sdk > express-rate-limit >
ip-address`, `@lhci/cli > tmp`. Upstream releases that bump those
transitives have not landed (or never will, in some cases).

Use `pnpm.overrides` with the upper-bound form (`pkg@<x.y.z`):
forces patched versions even when a parent specifies a tighter
range, and the rule expires on its own once a parent legitimately
resolves to a patched version (it stops matching).

Result: `pnpm audit --audit-level=moderate` reports zero
vulnerabilities. Remaining peer-dep warnings (`chokidar`,
`typescript`) are pre-existing mismatches inside nestjs-prisma /
@nestjs/schematics and out of scope for this PR.

Also fix a lint-staged trap surfaced while preparing this PR: the
glob `*.yaml` was matching `pnpm-lock.yaml`, so prettier reformatted
the entire lockfile on every dep-change commit (~9000 lines of
diff churn, with a non-zero risk of pnpm rejecting the rewritten
file). Tighten the glob to `!(pnpm-lock).{...,yaml}` so the
lockfile is left to pnpm's own formatter.
julien merged commit 25bfba97cb into main 2026-05-06 21:38:53 +02:00
julien deleted branch chore/deps/audit-overrides 2026-05-06 21:38:53 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#42