Skip to content

fix(deps): close Dependabot alerts across root, examples, and docs#198

Merged
7nohe merged 8 commits into
mainfrom
fix/dependabot-security-upgrades
Jul 20, 2026
Merged

fix(deps): close Dependabot alerts across root, examples, and docs#198
7nohe merged 8 commits into
mainfrom
fix/dependabot-security-upgrades

Conversation

@7nohe

@7nohe 7nohe commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Summary

Addresses all 207 open Dependabot alerts on main, in three tiers:

  • Transitive overrides (pnpm.overrides) pinning ~40 vulnerable transitive packages (axios, shell-quote, form-data, jsonpath-plus, etc.) to their first patched version, staying within each package's currently-used major to avoid breakage.
  • Same-major follow-ups: cross-spawn/esbuild were missed by the first override pass (root's own direct cross-spawn pin, and vite/vitest's bundled esbuild) — closed with a second pass. fast-xml-parser bumped 4→5 (only reaches @stoplight/prism-http-server, the dev-only mock server; verified prism mock still serves correctly).
  • Major version bumps, each verified independently and committed separately:
    • vitest 1→3 (root) — closes a critical "Vitest UI server arbitrary file read" advisory never backported to 1.x. Required bumping @vitest/coverage-v8 to match and adding dist/** to coverage.exclude (v3's coverage.all now reports files v1 silently skipped).
    • vite 5→6 across 4 examples (react-app, tanstack-router-app, react-router-6-app, react-router-7-app) — some vite CVEs were only patched starting 6.4.2/6.4.3.
    • react-router 7.0.0-pre.2→7.18.1 (react-router-7-app) — required to unblock the vite 6 bump, since @react-router/dev@7.0.0-pre.2 only accepted vite ^5.1.0. Migrated to stable framework-mode conventions: route config moved to react-router.config.ts, routes.ts uses export default, generated types are now a Route namespace imported from ./+types/route.
    • next.js 14→15 (nextjs-app) — several CVEs were never backported to 14.x.
    • astro 4→6 + @astrojs/starlight 0.28→0.40 (docs) — same story, plus Astro 6's legacy content collections removal (src/content/config.tssrc/content.config.ts with docsLoader()) and Starlight's social array syntax / autogenerate sidebar changes. valibot came along for free via the astro bump.

Also:

  • pnpm.packageExtensions teaches pnpm that ofetch (a new transitive dep pulled in by astro's unifont/unstorage) needs undiciofetch's own .d.mts does a bare import "undici" without declaring it as a dependency, which broke the root package's declaration: true build the moment ofetch entered the shared lockfile.
  • .claude/** excluded from vitest's test.exclude/coverage.exclude and biome's ignore list, since a concurrent worktree under .claude/worktrees/ was getting scanned and causing spurious failures.

Not in scope / follow-up filed separately: next build in examples/nextjs-app fails with a webpack module-resolution error on generated .gen.ts imports — reproduces identically on next 14.2.4, so it's a pre-existing issue unrelated to this bump (CI never ran next build for this example, only generate:api/test:generated).

Verification

For every commit: root build + test (vitest, 70/71 passing) + biome check ., plus per-example generate:apitest:generated, and for the major bumps additionally the real build (vite build / next build where it already worked / astro check && astro build) and, for the prism-http-server bump, a live prism mock smoke test.

Test plan

  • pnpm build && pnpm test on root
  • pnpm --filter <each-example> generate:api && pnpm --filter <each-example> test:generated
  • pnpm --filter @7nohe/react-app build, tanstack-router-app build, react-router-6-app build, react-router-7-app build
  • pnpm --filter docs build
  • pnpm biome check .

7nohe added 7 commits July 20, 2026 11:17
Add pnpm.overrides pinning ~40 vulnerable transitive packages (axios,
next, vite, jsonpath-plus, shell-quote, form-data, etc.) to their
first patched version reported by Dependabot, staying within each
package's currently-used major version to avoid breaking changes.
cross-spawn@^7.0.3 (root's own direct dependency) and the vite/vitest
-bundled esbuild were left unpinned in the previous override pass and
still resolved to vulnerable versions.
Closes the remaining critical Vitest UI-server arbitrary file
read/execute advisory, which was never backported to the 1.x line.
Requires bumping @vitest/coverage-v8 to match and adding dist/** and
the config file itself to the coverage exclude list, since v3's
coverage.all default now reports untested files that v1 silently
skipped.
react-app, tanstack-router-app, react-router-6-app, and
react-router-7-app all pin their own vite/@vitejs/plugin-react, so
the vite CVEs only fixed starting at 6.4.2/6.4.3 couldn't be closed
by the shared vite@5 override alone.

react-router-7-app was still on the 7.0.0-pre.2 prerelease, whose
@react-router/dev only accepts vite ^5.1.0 — bumping vite there
required moving it to the stable 7.18.1 line first. That in turn
required migrating to the stable framework-mode conventions:
- route config moves from vite-plugin options to react-router.config.ts
- routes.ts must use `export default` instead of a named export
- generated route types are exported as a `Route` namespace from
  `./+types/route` (folder, not `./+types.route`) instead of being
  the module's own namespace
- test:generated must run `typegen` first now that `.react-router/
  types` is required for the +types imports to resolve
Several next.js CVEs affecting this example were never backported to
the 14.x line and only close at 15.5.16.

Verified via generate:api + test:generated (the same checks CI runs
for this example). `next build` was also tried but fails identically
on 14.2.4 before this change — a pre-existing, unrelated module
resolution issue (openapi/requests/*.gen.ts importing "./client.gen.js"
that webpack can't resolve), not something this bump introduced or
regresses. Left as-is; worth its own follow-up.
Several astro CVEs affecting the docs site were only patched starting
at astro 5.x/6.x, with no 4.x backport. Starlight has to move in
lockstep (0.40.0 is the first release supporting astro ^6.4.5).

Astro 6 removes legacy content collections, so src/content/config.ts
moves to src/content.config.ts with an explicit docsLoader(), and
Starlight 0.33/0.39 changed the sidebar `social` array syntax and
dropped `autogenerate` blocks with a `label` (astro.config.mjs).

Also:
- add a pnpm.packageExtensions entry teaching pnpm that ofetch (a new
  transitive dependency pulled in by astro's unifont/unstorage) needs
  undici, since ofetch's own .d.mts does a bare `import "undici"` for
  ambient types without declaring it as a real dependency - under
  pnpm's strict linking this left it unresolvable and broke the root
  package's declaration build (declaration: true) the moment ofetch
  entered the shared lockfile, even though ofetch only belongs to
  docs' dependency tree.
- exclude .claude/** from vitest's test glob and biome's lint scope,
  since a concurrent worktree under .claude/worktrees/ was getting
  picked up and causing spurious failures unrelated to this change.
fast-xml-parser only reaches @stoplight/prism-http-server (the dev-only
mock server used by each example's `dev:mock` script), so the major
bump is low-risk; verified prism mock still serves the petstore spec
correctly after the upgrade.

Also add .claude/** to vitest's coverage.exclude (test.exclude already
had it) — the v8 coverage provider's untested-files scan isn't scoped
by test.exclude, so it was reaching into a concurrent worktree under
.claude/worktrees/ and racing its build output.
@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
openapi-react-query-codegen Ready Ready Preview, Comment Jul 20, 2026 6:34am

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 98.99% (🎯 95%) 1965 / 1985
🟢 Statements 98.99% (🎯 95%) 1965 / 1985
🟢 Functions 100% (🎯 95%) 49 / 49
🟢 Branches 92.59% (🎯 90%) 200 / 216
File CoverageNo changed files found.
Generated in workflow #421 for commit a742dbd by the Vitest Coverage Report Action

The blanket "esbuild": "0.25.0" pnpm.overrides entry forced every
consumer to that exact version regardless of its own declared range.
That was fine when only vite 5.4.21/vitest's bundled esbuild (which
resolved to the vulnerable 0.20.2/0.21.5/0.23.1) needed the fix, but
after upgrading astro to 6.4.8 (which bundles vite 7.3.6, requiring
esbuild ^0.27.0 || ^0.28.0, with astro itself wanting ^0.27.3) the
same override silently downgraded them to an out-of-range 0.25.0,
putting the docs build and its bundler on an unsupported combination.

Removing the override lets astro/vite7 (and vite 6.4.3 across the
examples) resolve their own compatible esbuild version naturally
(0.27.7). What's left unpatched is esbuild 0.21.5 (vite 5.4.21, only
reachable via @vitest/mocker's internal vite peer) and 0.23.1 (tsx's
peer, used by vite-node/router-generator dev tooling) - both are
already the latest patch available within their dependents' declared
ranges (vitest 3.2.7 is the latest 3.x release), and the underlying
advisory is about esbuild's dev server accepting cross-origin
requests, which doesn't apply to how these internal, non-network-
exposed instances get used here. Forcing them to 0.25+ would violate
their dependents' declared peer ranges for no practical security
benefit, per the Codex review on this branch.

Verified: root build+test, docs build, and per-example generate:api +
test:generated + real build (vite build x4, react-router build) all
still pass after removing the override.
@7nohe
7nohe merged commit 6f9e8ae into main Jul 20, 2026
5 checks passed
@7nohe
7nohe deleted the fix/dependabot-security-upgrades branch July 20, 2026 13:58
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