Skip to content

fix(deps): clear all 14 frontend advisories, and unblock npm ci - #52

Merged
sagehen03 merged 3 commits into
mainfrom
deps/frontend-audit
Aug 11, 2026
Merged

fix(deps): clear all 14 frontend advisories, and unblock npm ci#52
sagehen03 merged 3 commits into
mainfrom
deps/frontend-audit

Conversation

@sagehen03

Copy link
Copy Markdown
Collaborator

Clears all 14 advisories in frontend/package-lock.json — 3 critical, 8 high,
2 moderate, 1 low — and makes the result installable by CI.

Why this wasn't a one-liner

npm update on its own fixes every advisory. The problem is the lockfile it
produces, which npm ci refuses — and frontend-ci.yml runs npm ci, so that
result cannot ship. It fails with two messages that contradict each other:

Invalid: lock file's cac@7.0.0 does not satisfy cac@6.7.14
Missing: cac@7.0.0 from lock file

The cause is @bomb.sh/tab, pulled in by @nuxt/cli. It declares cac and
commander as optional peer dependencies, so an absent or mismatched
version should be ignored. But both are present hoisted for other consumers —
cac@7 for fast-npm-meta, commander@11 for svgo. npm hoists versions its
own optional-peer ranges then reject, and it validates that strictly under ci
while tolerating it under install.

@bomb.sh/tab@0.0.22 widens the cac peer to ^6.7.14 || ^7.0.0. Overriding to
it lets npm hoist a tree that satisfies every consumer:

before (rejected) after
root cac 7.0.0 6.7.14
root commander 11.1.0 15.0.0
fast-npm-meta/…/cac 7.0.0
svgo/…/commander 11.1.0

That one override is the entire fix. No direct dependency's declared range
changed
— every advisory's fix was already inside the range the lockfile had
gone stale against.

What moved

nuxt         3.21.7  -> 3.21.11      axios         1.17.0 -> 1.19.0
postcss      8.5.15  -> 8.5.26       tar           7.5.16 -> 7.5.22
shell-quote  1.8.3   -> 1.10.0       nanoid        3.3.12 -> 3.3.18
@nuxt/devtools 3.2.4 -> 3.4.1        svgo          4.0.1  -> 4.0.2
esbuild      0.27.7  -> 0.28.2       immutable     5.1.5  -> 5.1.9
form-data    4.0.5   -> 4.0.6        launch-editor 2.13.2 -> 2.14.1
brace-expansion 5.0.6 -> 5.0.9

All patch or minor. No direct dependency crosses a major.

What was actually exposed

Worth separating, because severity alone overstates it. All three criticals
were build- or dev-time only: the @nuxt/devtools unauthenticated RPC (reaches
a developer's host, not the server), shell-quote, and tar.

The one that reached shipped code was nuxt: server-side RCE via runtime
template injection in server island props (>=3.4.0 <3.21.10), plus a route
rule auth bypass where mixed-case paths silently skipped appMiddleware
gates. axios is also runtime, carrying ten advisories — mostly prototype
pollution and DoS.

Verification

  • npm ci from a clean directory — passes (this is the check that failed before)
  • npm audit — 0 vulnerabilities
  • 191 frontend tests pass
  • nuxt build completes

Supersedes

These Dependabot PRs are covered by this change and can close once it merges:
#47 (form-data 4.0.6), #46 (launch-editor 2.14.1), #45 (shell-quote 1.8.4).

🤖 Generated with Claude Code

https://claude.ai/code/session_01J6tzeGkxhib4vWYYYzR4Md

sagehen03 and others added 3 commits August 11, 2026 14:14
`npm update` alone fixes every advisory but produces a lockfile `npm ci`
rejects -- and frontend-ci.yml runs `npm ci`, so the update was unshippable.
It failed with two messages that contradict each other:

    Invalid: lock file's cac@7.0.0 does not satisfy cac@6.7.14
    Missing: cac@7.0.0 from lock file

The cause is @bomb.sh/tab, pulled in by @nuxt/cli. It declares cac and
commander as OPTIONAL peers, so they should be ignored -- but both happen to
be present hoisted for other consumers (cac@7 for fast-npm-meta, commander@11
for svgo). npm hoisted versions its own optional-peer ranges then reject,
and validates strictly on ci while tolerating it on install.

@bomb.sh/tab 0.0.22 widens the cac peer to `^6.7.14 || ^7.0.0`. Overriding to
it lets npm hoist a tree that satisfies everyone: cac@6.7.14 and commander@15
at the root, with cac@7 nested under fast-npm-meta and commander@11 under
svgo. That single override is the whole fix; no direct dependency's declared
range changed, because every advisory's fix was already inside the range the
lockfile had gone stale against.

    nuxt      3.21.7  -> 3.21.11     axios     1.17.0 -> 1.19.0
    postcss   8.5.15  -> 8.5.26      tar       7.5.16 -> 7.5.22
    shell-quote 1.8.3 -> 1.10.0      nanoid    3.3.12 -> 3.3.18

All patch or minor; no direct dependency crosses a major.

Worth knowing what was actually exposed: of the three criticals, all were
build- or dev-time (@nuxt/devtools RPC, shell-quote, tar). The one that
reached shipped code was nuxt's server-side RCE via runtime template
injection in server island props (>=3.4.0 <3.21.10), alongside a route-rule
auth bypass for mixed-case paths.

Verified: npm ci from a clean directory, npm audit reports 0, 191 frontend
tests pass, and nuxt build completes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J6tzeGkxhib4vWYYYzR4Md
`branches: - "*"` never matched dependabot/npm_and_yarn/..., because a single
star stops at a slash in GitHub's glob syntax. Every Dependabot PR in this
repo has therefore run zero CI -- `gh pr checks 47` reports "no checks
reported" -- which is why none of them could be judged safe to merge, and why
they have sat open since June. The branch carrying this fix hit the same wall.

"**" crosses slashes. The deploy jobs in both workflows are gated on
`github.ref == 'refs/heads/main'`, so this widens what gets tested, never what
gets deployed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J6tzeGkxhib4vWYYYzR4Md
api-ci.yml and falcon-cli-e2e.yml both list themselves in their path filters
so a CI fix can be validated without an unrelated code change. This one did
not, so the branch-glob fix in the previous commit could not run the frontend
build that proves it works.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J6tzeGkxhib4vWYYYzR4Md
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