Skip to content

deps: patch high-severity dependency vulnerabilities - #147

Open
adelrodriguez wants to merge 2 commits into
mainfrom
t3code/fix-high-dependabot-vulnerabilities
Open

deps: patch high-severity dependency vulnerabilities#147
adelrodriguez wants to merge 2 commits into
mainfrom
t3code/fix-high-dependabot-vulnerabilities

Conversation

@adelrodriguez

@adelrodriguez adelrodriguez commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Dependabot reports high-severity vulnerabilities in the direct nanoid and sharp dependencies. This updates both packages to patched releases and forces the whole resolved graph onto them, so no vulnerable copy is left installed.

  • sharp 0.34.50.35.3 in apps/docs (GHSA-f88m-g3jw-g9cj, High). The direct pin alone is inert: nothing in the repo imports sharp, and the real consumers are astro's built-in image service plus next and @wxt-dev/auto-icons, each of which bun kept on its own nested 0.34.5. A root overrides entry dedupes all three onto 0.35.3, which also collapses the ~190 nested duplicate lock entries the naive bump produced.
  • nanoid 5.1.65.1.16 in packages/utils (GHSA-28wg-ghj8-5hjv / CVE-2026-67214, High). @scalar/types declares ^5.1.6 but bun preserved a stale nested 5.1.6; dropping that lock entry lets it dedupe onto the root 5.1.16. An override is not usable here because bun ignores scoped overrides and a flat one would drag the nanoid@3.x consumers onto ESM-only 5.x.

Compatibility: sharp 0.35 needs Node >= 20.9 and the repo targets Node 24 everywhere. next is a devDependency reached only through @react-email/ui, and @wxt-dev/auto-icons calls only the sharp() constructor, so overriding past their declared ^0.34.5 is safe.

Verification

The declared-version checks alone cannot detect a vulnerable copy left in the tree, so the resolved graph is asserted directly after rm -rf node_modules && bun install --frozen-lockfile:

  • ls -d node_modules/.bun/sharp@* → only sharp@0.35.3
  • ls -d node_modules/.bun/@img+sharp-libvips-linux-x64@* → only 1.3.2; the vulnerable 1.2.4 is gone
  • ls -d node_modules/.bun/nanoid@*3.3.16 and 5.1.16; no 5.1.6
  • every */node_modules/sharp symlink (astro, next, @wxt-dev/auto-icons) points at sharp@0.35.3
  • importing sharp from realpath node_modules/.bun/astro@*/node_modules/astro reports vips: 8.18.3 (the patched libvips) and round-trips a resize
  • bun audit no longer reports either advisory

Also run: bun run check, bun run check:monorepo, bun test, bun run build --filter=docs.

Out of scope, noted for follow-up: bun audit flags the transitive nanoid@3.3.16 under a different advisory, GHSA-2v37-7h3g-55p8 (<3.3.18, High). It predates this branch and every consumer's ^3.3.x range accepts the fix, so it is a clean separate change.

Created with GPT-5.6 Sol through the Codex harness in T3 Code.

Pullfrog  | View workflow run | via Pullfrog | Using Claude Opus𝕏

@vercel

vercel Bot commented Aug 17, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
init Ready Ready Preview Aug 18, 2026 2:02pm
init-docs Ready Ready Preview Aug 18, 2026 2:02pm

Request Review

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The nanoid half of this lands correctly, but the sharp half is inert — a fresh install of this lockfile still puts every real sharp consumer on the vulnerable 0.34.5, and 0.35.3 ends up with zero consumers.

Reviewed changes — a two-package security bump plus the regenerated Bun lockfile, checked against the published advisories, against this repo's Node/runtime targets, and against what bun install actually materializes on disk.

  • sharp 0.34.5 → 0.35.3 in apps/docs — targets GHSA-f88m-g3jw-g9cj (High, CVSS 7.0), whose root cause is the bundled libvips binaries rather than sharp's JS.
  • nanoid 5.1.6 → 5.1.16 in packages/utils — targets GHSA-28wg-ghj8-5hjv / CVE-2026-67214 (High, CVSS 8.2). 5.1.16 is exactly the minimum patched version. Worth noting the older CVE-2024-55565 (fixed in 5.0.9) does not apply to 5.1.6, so this newer advisory is the real justification.
  • bun.lock regeneration — the large majority of the +190 lines are new nested entries that pin the OLD sharp@0.34.5 and nanoid@5.1.6 for transitive consumers.

Both target versions are the right choices, and compatibility is clean: sharp 0.35.0 requires Node >= 20.9.0, this repo targets Node 24 everywhere (root engines, .nvmrc, all three workflows), no source file imports sharp directly, and the new @types/node optional peer plus the freebsd/webcontainers wasm optional deps are platform-gated and inert on Linux CI.

⚠️ Nothing in the stated verification can detect that the vulnerable code is still installed

bun run check, bun run check:monorepo, bun test and bun run build --filter=docs all pass while sharp@0.34.5 and its @img/sharp-libvips-linux-x64@1.2.4 binary remain in the tree. That is exactly how a dependency-patch PR can look green and still ship the vulnerability, and it will happen again on the next advisory unless something asserts on the resolved graph rather than on the declared version.

This also raises a scope question only you can settle: is the goal to remove the vulnerable code from the installed tree, or to clear Dependabot's direct-dependency alert? Those need different fixes. As written the PR achieves the second for sharp and the first only for @init/utils' nanoid.

Technical details
# Post-patch verification does not cover the resolved dependency graph

## Affected sites
- PR description "Verification" list — every listed command passes with
  `sharp@0.34.5`, `@img/sharp-libvips-linux-x64@1.2.4` and `nanoid@5.1.6` still
  installed. None of them inspect resolved versions.

## Required outcome
- A post-bump check that fails when a known-vulnerable version is still present
  anywhere in the resolved tree, not merely absent from a `package.json`.

## Suggested approach (optional)
- The cheap manual form, run after `rm -rf node_modules && bun install --frozen-lockfile`:
  `ls -d node_modules/.bun/sharp@* node_modules/.bun/nanoid@*`
- Per the repo's own learnings, only a full `rm -rf node_modules` gives a
  trustworthy reading — bun leaves stale symlinks in `.bun` across incremental
  installs and successive runs disagree with each other.

## Open questions for the human
- Remove the vulnerable code from the tree, or just clear the direct-dependency
  alert? If only the latter, the `sharp` bump is doing nothing beyond silencing
  Dependabot and `apps/docs` is carrying an unused dependency.
- `next@16.2.6` (via `@react-email/ui`, not production-serving) and
  `@wxt-dev/auto-icons` both cap at `^0.34.5` and cannot take 0.35.x without an
  override that violates their declared range. Is accepting their `0.34.5`
  copies the intended end state?

ℹ️ Nitpicks

  • bun.lock new line 875: the root @emnapi/runtime entry is downgraded 1.11.3 → 1.11.2 while @oxc-resolver/binding-wasm32-wasi's nested 1.11.2 entry is dropped. It is a hoist shuffle and inert in practice (@emnapi/runtime is wasm32-gated and never installs on linux-x64 or darwin), but it is unexplained churn riding along in a security-scoped diff.

Pullfrog  | Fix all ➔Fix 👍s ➔View workflow run | Using Claude Opus𝕏

Comment thread apps/docs/package.json
Comment thread bun.lock Outdated
Comment thread bun.lock
"@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="],

"@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
"@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated downgrade: the root @emnapi/runtime drops from 1.11.3 to 1.11.2 here while the @oxc-resolver/binding-wasm32-wasi nested 1.11.2 entry is removed below. It appears inert (wasm32-gated, never installed on linux-x64), but it is churn unrelated to either advisory.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving this as-is, but here is the explanation. @img/sharp-wasm32 widened its requirement from ^1.7.0 to ^1.11.1 between sharp 0.34.5 and 0.35.3, so bun re-picked the hoist winner: @oxc-resolver/binding-wasm32-wasi's 1.11.2 moved up to the root and sharp's 1.11.3 moved into a nested @img/sharp-wasm32/@emnapi/runtime entry. Same entry count, no version added or removed from the graph, and @emnapi/runtime still installs on no platform we build for (ls -d node_modules/.bun/@emnapi+runtime@* finds nothing after a clean install). Pinning it back would mean adding an override for a package that is never installed, so I would rather carry the two lines of movement.

Pullfrog  | View workflow run | via Pullfrog | Using Claude Opus𝕏

@pullfrog

pullfrog Bot commented Aug 18, 2026

Copy link
Copy Markdown

The review was right: both bumps were declared but only nanoid in @init/utils actually reached its consumer. Fixed in 5988333 so no vulnerable copy is installed.

sharp — added a root overrides entry for 0.35.3. Bun honours it for all three nested edges, so astro, next and @wxt-dev/auto-icons now share one sharp@0.35.3 and @img/sharp-libvips-linux-x64@1.2.4 (the binary carrying GHSA-f88m-g3jw-g9cj) is gone. Importing sharp through astro's real path reports vips: 8.18.3. Overriding past next/@wxt-dev/auto-icons' declared ^0.34.5 is safe: next is a devDependency reached only via @react-email/ui, and auto-icons calls only the sharp() constructor.

nanoid — bun ignores scoped overrides ("@scalar/types/nanoid" silently, the nested-object form with an explicit "does not support nested overrides" warning), and a flat override would drag postcss/expo-router/@react-navigation/* off 3.3.16 onto ESM-only 5.x. Deleting the stale nested lock entry was enough — bun re-resolved @scalar/types onto the root 5.1.16 that its own ^5.1.6 range already allowed.

Side effect worth noting: the override collapsed the duplicate entries, so bun.lock went from +190 lines to +4/−156. The @emnapi/runtime nitpick I left in place with an explanation — it is a hoist-winner swap caused by @img/sharp-wasm32 widening ^1.7.0^1.11.1, and the package installs on no platform we build for, so an override for it would be pure ceremony. That thread is left open for you.

Verified after rm -rf node_modules && bun install --frozen-lockfile by inspecting the resolved store rather than the package.json diff, plus bun run check, bun run check:monorepo, bun test, bun run build --filter=docs, and bun audit. PR body updated with those commands, since the previous verification list could pass with the vulnerability still installed.

One finding I deliberately did not bundle: bun audit flags the transitive nanoid@3.3.16 under GHSA-2v37-7h3g-55p8 (<3.3.18, High). It predates this branch and every consumer's ^3.3.x range accepts the fix, so it is a clean separate change.

Task list (5/5 completed)
  • Checkout PR 147 branch
  • Read review threads
  • Verify and address each comment
  • Commit and push
  • Reply and resolve threads

Pullfrog  | View workflow run | via Pullfrog | Using Claude Opus𝕏

The direct bumps left every real consumer on the vulnerable copies: astro, next and @wxt-dev/auto-icons each kept a nested sharp@0.34.5 with the libvips 1.2.4 binary from GHSA-f88m-g3jw-g9cj, and @scalar/types kept a nested nanoid@5.1.6 from GHSA-28wg-ghj8-5hjv.

Add a root sharp override so all three consumers dedupe onto 0.35.3, and drop the stale nested @scalar/types/nanoid entry so it dedupes onto the root 5.1.16 that its own ^5.1.6 range already allows.

After rm -rf node_modules && bun install --frozen-lockfile the store holds exactly one sharp (0.35.3, libvips 8.18.3) and no nanoid@5.1.6. This also collapses the 190 nested duplicate entries the first attempt added.
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