chore(security): override vite + esbuild past vitepress's vulnerable transitives #159

Merged
julien merged 1 commits from chore/security-vite-esbuild-overrides into main 2026-05-15 22:18:08 +02:00
Owner

Summary

Unblocks pnpm ci:audit. Two moderate vulnerabilities surfaced after the docs-site chantier (#154):

Advisory Package Vulnerable Patched Path
GHSA-67mh-4wv8-2f99 esbuild ≤ 0.24.2 ≥ 0.25.0 . > vitepress > vite > esbuild
GHSA-4w7w-66w2-5vf9 vite ≤ 6.4.1 ≥ 6.4.2 . > vitepress > vite

Both come from VitePress 1.6.4's pinned dep tree (vite@5.4.21 → esbuild@0.21.5). The rest of the workspace was already on vite 8.0.13 + esbuild 0.27.3 — only the VitePress branch was stuck on the vulnerable line.

What lands

Two new entries in package.json's existing pnpm.overrides block:

"esbuild@<0.25.0": ">=0.25.0",
"vite@<6.4.2":     ">=6.4.2",

Same version-selector pattern as the other overrides already in the file (axios, follow-redirects, ip-address, …). The override only kicks in when the resolved version is in the vulnerable range, so it becomes a no-op the day the underlying dep ships a clean version of its own.

After pnpm install, the resolver picks vite 7.3.2 + esbuild 0.27.3 for the VitePress branch (the workspace's other vite consumers stay on 8.0.13, deduped on esbuild).

Why couldn't we pin a patched vite 5.x?

The vite team did not backport the security fix to the 5.x line. vite@5.4.22 is not published — the latest 5.x stays at 5.4.21, which is vulnerable. The only path forward is to let pnpm pick a patched 6.x or 7.x major. Verified that VitePress 1.6.4 still:

  • builds cleanly (pnpm docs:build succeeds in ~4 s, down from 9 s on the older vite);
  • renders Mermaid (regression fence in .gitea/workflows/docs-site.yml still grep-matches class="mermaid" / <svg> in ADR-0009's HTML);
  • runs the dev server (pnpm docs:dev boots, the dayjs CJS-interop fix from #156 still applies for the same reason — Mermaid's CJS deps need pre-bundling regardless of vite major).

Why didn't Renovate propose this PR itself?

Root cause: both vite and esbuild are transitive dependencies — declared by vitepress, not by us. Renovate's vulnerabilityAlerts flow handles direct package.json deps. For pnpm transitives, the remediation would have to land in pnpm.overrides, which the renovatebot/renovate:40 image doesn't write automatically.

Adjacent points:

  • The Renovate workflow runs on a daily 03:00 UTC cron only (plus manual dispatch). If the user wants an immediate dashboard refresh now, the workflow accepts workflow_dispatch — fire it once from the Gitea Actions UI.
  • After this PR merges, Renovate's dashboard should also stop flagging these advisories (the overrides count as remediation).
  • Renovate config itself is unchanged — no ignorePaths, no exclude of vite/esbuild/vitepress. The silence was purely about the transitive-remediation gap, not a config bug.

Test plan

  • pnpm install — clean, no peer warnings beyond the pre-existing nestjs-prisma → chokidar one.
  • pnpm audit --audit-level=moderate"No known vulnerabilities found".
  • pnpm docs:build — clean build in ~4 s.
  • Mermaid regression fence — grep 'class="mermaid"' docs/.vitepress/dist/decisions/0009-…html matches.
  • pnpm ci:audit on CI — should now pass (the goal of this PR).
  • Manual smoke: pnpm docs:dev, navigate to /decisions/0009-…, confirm the OIDC sequence diagram renders. Dark-mode toggle still flips theme.

Follow-ups (optional)

  • Trigger the Renovate workflow manually (Gitea Actions → Renovate → Run workflow) so the Dependency Dashboard refreshes against this overridden state.
  • If we hit this transitive-remediation gap again, consider raising a renovateConfig.transitiveRemediation story or switching the workflow to renovate/renovate:latest — newer point releases sometimes ship better pnpm-overrides authoring. Not urgent.
## Summary Unblocks `pnpm ci:audit`. Two moderate vulnerabilities surfaced after the docs-site chantier (#154): | Advisory | Package | Vulnerable | Patched | Path | | --- | --- | --- | --- | --- | | [GHSA-67mh-4wv8-2f99](https://github.com/advisories/GHSA-67mh-4wv8-2f99) | esbuild | ≤ 0.24.2 | ≥ 0.25.0 | `. > vitepress > vite > esbuild` | | [GHSA-4w7w-66w2-5vf9](https://github.com/advisories/GHSA-4w7w-66w2-5vf9) | vite | ≤ 6.4.1 | ≥ 6.4.2 | `. > vitepress > vite` | Both come from VitePress 1.6.4's pinned dep tree (`vite@5.4.21 → esbuild@0.21.5`). The rest of the workspace was already on vite 8.0.13 + esbuild 0.27.3 — only the VitePress branch was stuck on the vulnerable line. ## What lands Two new entries in `package.json`'s existing `pnpm.overrides` block: ```json "esbuild@<0.25.0": ">=0.25.0", "vite@<6.4.2": ">=6.4.2", ``` Same version-selector pattern as the other overrides already in the file (axios, follow-redirects, ip-address, …). The override only kicks in when the resolved version is in the vulnerable range, so it becomes a no-op the day the underlying dep ships a clean version of its own. After `pnpm install`, the resolver picks **vite 7.3.2** + **esbuild 0.27.3** for the VitePress branch (the workspace's other vite consumers stay on 8.0.13, deduped on esbuild). ## Why couldn't we pin a patched vite 5.x? The vite team did **not** backport the security fix to the 5.x line. `vite@5.4.22` is not published — the latest 5.x stays at 5.4.21, which is vulnerable. The only path forward is to let pnpm pick a patched 6.x or 7.x major. Verified that VitePress 1.6.4 still: - builds cleanly (`pnpm docs:build` succeeds in ~4 s, down from 9 s on the older vite); - renders Mermaid (regression fence in `.gitea/workflows/docs-site.yml` still grep-matches `class="mermaid"` / `<svg>` in ADR-0009's HTML); - runs the dev server (`pnpm docs:dev` boots, the dayjs CJS-interop fix from #156 still applies for the same reason — Mermaid's CJS deps need pre-bundling regardless of vite major). ## Why didn't Renovate propose this PR itself? **Root cause: both vite and esbuild are transitive dependencies** — declared by vitepress, not by us. Renovate's `vulnerabilityAlerts` flow handles **direct** package.json deps. For pnpm transitives, the remediation would have to land in `pnpm.overrides`, which the renovatebot/renovate:40 image doesn't write automatically. Adjacent points: - The Renovate workflow runs on a daily 03:00 UTC cron only (plus manual dispatch). If the user wants an immediate dashboard refresh now, the workflow accepts `workflow_dispatch` — fire it once from the Gitea Actions UI. - After this PR merges, Renovate's dashboard should also stop flagging these advisories (the overrides count as remediation). - Renovate config itself is unchanged — no `ignorePaths`, no exclude of vite/esbuild/vitepress. The silence was purely about the transitive-remediation gap, not a config bug. ## Test plan - [x] `pnpm install` — clean, no peer warnings beyond the pre-existing `nestjs-prisma → chokidar` one. - [x] `pnpm audit --audit-level=moderate` — **"No known vulnerabilities found"**. - [x] `pnpm docs:build` — clean build in ~4 s. - [x] Mermaid regression fence — `grep 'class="mermaid"' docs/.vitepress/dist/decisions/0009-…html` matches. - [ ] `pnpm ci:audit` on CI — should now pass (the goal of this PR). - [ ] Manual smoke: `pnpm docs:dev`, navigate to `/decisions/0009-…`, confirm the OIDC sequence diagram renders. Dark-mode toggle still flips theme. ## Follow-ups (optional) - Trigger the Renovate workflow manually (Gitea Actions → Renovate → Run workflow) so the Dependency Dashboard refreshes against this overridden state. - If we hit this transitive-remediation gap again, consider raising a `renovateConfig.transitiveRemediation` story or switching the workflow to `renovate/renovate:latest` — newer point releases sometimes ship better pnpm-overrides authoring. Not urgent.
julien added 1 commit 2026-05-15 22:17:48 +02:00
chore(security): override vite + esbuild past vitepress's vulnerable transitives
CI / commits (pull_request) Successful in 2m22s
CI / scan (pull_request) Successful in 2m31s
CI / a11y (pull_request) Successful in 2m24s
CI / check (pull_request) Failing after 5m20s
Docs site / build (pull_request) Successful in 2m6s
CI / perf (pull_request) Successful in 6m29s
00504352c1
`pnpm audit` flagged two moderate vulnerabilities introduced by the
docs-site chantier (#154):

* esbuild ≤ 0.24.2 — dev-server reflection of arbitrary cross-site
  requests (GHSA-67mh-4wv8-2f99).
* vite ≤ 6.4.1 — path traversal via optimized-deps `.map` handling
  (GHSA-4w7w-66w2-5vf9).

Both come from VitePress 1.6.4's pinned dep tree
(`vitepress → vite@5.4.21 → esbuild@0.21.5`). The rest of the
workspace already runs vite 8.0.13 + esbuild 0.27.3 (via @nx/vite,
@analogjs/vite-plugin-angular, Vitest) — only the VitePress branch
was stuck on the vulnerable line.

The vite team did not backport the security fix to the 5.x line
(`vite@^5.4.22` is not published — latest 5.x stays at 5.4.21,
which is vulnerable). The only path forward is to let pnpm pick a
patched major. With the override below, pnpm resolves vitepress's
`vite ^5.0.0` constraint up to vite 7.3.2 — VitePress 1.6.4 runs
against it cleanly: `docs:build` succeeds in ~4 s and the Mermaid-
in-ADR-0009 regression fence still passes.

Pattern matches the existing `pnpm.overrides` entries in this
project (axios, follow-redirects, ip-address, etc.) — version-
selector form `<package>@<vulnerable-range>` so the override
becomes a no-op when the underlying dep eventually ships a clean
version of its own.

Why Renovate didn't propose this PR itself: vite and esbuild are
**transitive** dependencies (declared by vitepress, not by us).
Renovate's `vulnerabilityAlerts` flow handles direct deps; for
pnpm transitives it would have to write to `pnpm.overrides`
itself, which the v40 image doesn't do out of the box. The override
is the manual remediation that Renovate would write if it could.
julien merged commit 779061660b into main 2026-05-15 22:18:08 +02:00
julien deleted branch chore/security-vite-esbuild-overrides 2026-05-15 22:18:09 +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#159