Skip to content

fix(deps): clear 10 fresh audit advisories — undici 8.10.0 + brace-expansion 5.0.9 overrides - #92

Merged
tps-flint merged 1 commit into
mainfrom
fix/undici-advisories
Aug 22, 2026
Merged

fix(deps): clear 10 fresh audit advisories — undici 8.10.0 + brace-expansion 5.0.9 overrides#92
tps-flint merged 1 commit into
mainfrom
fix/undici-advisories

Conversation

@tps-flint

Copy link
Copy Markdown
Contributor

No issue: fresh upstream advisories. The Dependency Audit lane went red on #91 (and would on any PR) — nothing in any open diff pulls these in; they are new advisories published against bob's existing tree.

What the audit actually showed

bun audit on main: 10 vulnerabilities (3 high, 7 moderate) — 8 entries against undici (two installed instances: 8.5.0 exact-pinned by @earendil-works/pi-coding-agent, 6.27.0 via the discord.js › @discordjs/rest chain) and 2 high against brace-expansion (the existing ^5.0.7 override now falls inside fresh advisory ranges).

Advisories and resolving versions

GHSA Severity Package Vulnerable (installed) First patched Resolved to
GHSA-4cwx-7wf7-3272 (cache-directive disclosure + parse crash) high undici 8.5.0 (>=8.0.0 <8.9.0) 8.9.0 8.10.0
GHSA-8xcm-r25x-g524 (response desync via retry) moderate undici 8.5.0, 6.27.0 8.9.0 / 6.28.0 8.10.0
GHSA-m8rv-5g2x-5cg5 (CRLF injection via blob type) moderate undici 8.5.0, 6.27.0 8.9.0 / 6.28.0 8.10.0
GHSA-jr45-8vmc-qm54 (Cache-Control whitespace disclosure) moderate undici 8.5.0 (>=7.0.0 only) 8.9.0 8.10.0
GHSA-v3r7-h72x-cjcm (cookie attribute injection) moderate undici 8.5.0, 6.27.0 8.9.0 / 6.28.0 8.10.0
GHSA-mh99-v99m-4gvg (DoS, unbounded expansion) high brace-expansion 5.0.7 (>=4.0.0 <5.0.8) 5.0.8 5.0.9
GHSA-rgw5-rvv9-x895 (DoS, CVE-2026-14257 bypass) high brace-expansion 5.0.7 (>=4.0.0 <5.0.9) 5.0.9 5.0.9

Patched-version data read from each GHSA's vulnerabilities[].first_patched_version (GitHub advisories API).

Mechanism — and why the undici override is flat

Repo convention is the top-level overrides block (ws, @discordjs/rest, protobufjs, brace-expansion already live there); this PR stays inside it:

  • brace-expansion: ^5.0.7^5.0.9 (existing override, floor raised).
  • undici: new ^8.9.0 override → resolves 8.10.0 for all instances.

A scoped fix (only pi-coding-agent's pinned 8.5.0) would have been narrower, but bun 1.3.10 supports neither nested overrides (warns and ignores) nor yarn-style scoped resolutions (silently ignored — verified by deleting the lock and fully re-resolving: the pinned 8.5.0 didn't move). Alternatives considered: bumping the parent (pi-coding-agent 0.79.10 → 0.84.1+, which pins undici 8.9.0) is a five-minor jump of the core agent runtime — wrong blast radius for a security lane; hand-editing bun.lock is not a supported channel.

Collateral: the discord chain is forced 6.27.0 → 8.10.0, past its declared ^6.27.0. Its complete undici API surface is request, Headers, FormData (@discordjs/rest) and fetch (discord.js util) — verified by grep of the installed dist. Probed live, not assumed: a local HTTP server driven through @discordjs/rest's real REST#get path on undici 8.10.0 (response parsed, versioned route observed), plus undici.fetch and a discord.js import — all pass. When @discordjs/rest ships a release declaring undici ^8 natively, the override can drop.

All patched versions clear bunfig's 7-day minimumReleaseAge gate (undici 8.10.0: 2026-08-03; brace-expansion 5.0.9: 2026-07-30). Nothing allowlisted, no policy changes.

Verification

  • bun audit: 10 vulnerabilities (3 high, 7 moderate) → 0 (No vulnerabilities found)
  • bun install --frozen-lockfile: clean (CI-lane parity)
  • bun test: 332 pass / 0 fail (identical to main baseline)
  • tsc --noEmit clean; biome unchanged (same 1 pre-existing warning)
  • Lock diff is surgical: the two override targets plus the two scoped v6 undici entries collapsing into the single 8.10.0 resolution — nothing else moved

🤖 Generated with Claude Code

…pansion 5.0.9 overrides

No issue: fresh upstream advisories against the existing tree.

- undici: force ^8.9.0 (resolves 8.10.0) via the existing top-level
  overrides mechanism. Covers GHSA-4cwx-7wf7-3272 (high) and four
  moderates across both installed instances (pi-coding-agent's exact
  8.5.0 pin and the discord.js chain's 6.27.0).
- brace-expansion: bump the existing override ^5.0.7 -> ^5.0.9 for
  GHSA-mh99-v99m-4gvg / GHSA-rgw5-rvv9-x895 (both high; 5.0.7 fell
  inside the fresh <5.0.8 / <5.0.9 ranges).

bun 1.3.10 supports neither nested overrides (warns + ignores) nor
scoped resolutions (silently ignored — verified by full re-resolve),
so the undici force is flat: the discord chain moves 6.27.0 -> 8.10.0,
past its declared ^6.27.0. Its whole undici surface is request /
Headers / FormData / fetch; verified live against undici 8.10.0 with a
local-server probe through @discordjs/rest's real request path.

bun audit: 10 vulnerabilities (3 high, 7 moderate) -> 0.
bun test: 332 pass / 0 fail (unchanged). tsc + biome clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@tps-kern tps-kern 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.

Review: bob audit advisory clearance — undici 8.10.0 + brace-expansion 5.0.9 (#92)

Verdict: APPROVE. The flat undici override is blessed — the builder proved no narrower option works under bun 1.3.10, and the collateral is evidence-tested.

The judgment call: flat undici override forces discord chain 6.27.0 -> 8.10.0

BLESSED. This is the right call given the constraints, and the builder did the right verification work.

Why flat is the only option:

  • bun 1.3.10 does not support nested overrides (warns and ignores).
  • bun 1.3.10 silently ignores yarn-style scoped resolutions — verified by deleting the lock and fully re-resolving: the pinned 8.5.0 didn't move.
  • Hand-editing bun.lock is not a supported channel.
  • The alternative (bumping pi-coding-agent 0.79 -> 0.84) is a five-minor core-runtime jump — wrong blast radius for a security lane.

So the flat overrides block is the only mechanism that works. The discord chain (@discordjs/rest -> undici@6.27.0) is forced to 8.10.0, past its declared ^6.27.0. This is a major version jump for a transitive dep.

Why the collateral is acceptable:

The builder didn't assume — they verified:

  1. API surface grep: the discord chain's complete undici surface is request, Headers, FormData (@discordjs/rest) and fetch (discord.js util). These are stable undici APIs that haven't changed between 6.x and 8.x.

  2. Live probe: drove @discordjs/rest's real REST#get path through a local HTTP server on undici 8.10.0 — response parsed, versioned route observed. Plus undici.fetch and a discord.js import — all pass.

  3. Clean exit: when @discordjs/rest ships a release declaring undici ^8 natively, the override can drop. This is documented, not left as tribal knowledge.

The discord.js chain using an undici version outside its declared range is not ideal, but the alternative (leaving 10 known vulnerabilities, 3 high) is worse. The evidence-based verification is the right mitigation. The override is a security measure, not a casual version bump.

The two fixes

undici ^8.9.0 override -> resolves 8.10.0 for all instances (both pi-coding-agent's pinned 8.5.0 and the discord chain's 6.27.0). Clears:

brace-expansion ^5.0.7 -> ^5.0.9 (existing override, floor raised). Clears:

Both patched versions clear bunfig's 7-day minimumReleaseAge gate (undici 8.10.0: 2026-08-03; brace-expansion 5.0.9: 2026-07-30). Nothing allowlisted, no policy changes.

Lock diff

Surgical: the two override targets plus the two scoped v6 undici entries (@discordjs/rest/undici and discord.js/undici) collapsing into the single 8.10.0 resolution. Nothing else moved. 4 additions, 7 deletions across 2 files.

Verification

  • bun audit: 10 vulnerabilities (3 high, 7 moderate) -> 0 ("No vulnerabilities found")
  • bun install --frozen-lockfile: clean
  • bun test: 332/0 (identical to main baseline)
  • tsc --noEmit clean; biome unchanged

CI

All lanes green: Dependency Audit pass (this PR fixes the audit failure that was blocking #91), Build (TS strict) pass, Unit Tests pass, analyze pass, Published Artifact pass, Socket security pass.

Sequencing

#92 merges first, then #91 reruns its audit lane green. Correct — #91 was blocked by these advisories, not by anything in its own diff.

Good work. The "flat override is the only option under bun 1.3.10" finding is the key insight, and the live verification of the discord chain on 8.10.0 is the right mitigation for the forced version range violation.

@tps-kern tps-kern 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.

Review: clear 10 fresh audit advisories — undici + brace-expansion overrides

Verdict: Approved. Blessing the flat undici override.

The judgment call: flat undici override forces discord.js chain 6.27.0 → 8.10.0

This is the right call given the constraints:

  1. bun 1.3.10 doesn't support nested overrides (warns and ignores) or scoped resolutions (silently ignores — builder verified empirically by deleting the lock and re-resolving). A scoped fix was the preference but the tooling can't express it.

  2. The alternative (pi-coding-agent 0.79 → 0.84) is a five-minor core-runtime jump — wrong blast radius for a security lane. Security fixes should be surgical, not pulling in a new runtime version with its own behavior changes.

  3. The collateral is evidence-based, not assumed. The discord.js chain's complete undici API surface is request, Headers, FormData (@discordjs/rest) and fetch (discord.js util) — verified by grep of the installed dist. The real @discordjs/rest request path was probed live against a local HTTP server on undici 8.10.0 — response parsed, versioned route observed, passes. This is the right level of diligence for a major-version forced bump.

  4. The escape hatch is documented. When @discordjs/rest ships a release declaring undici ^8 natively, the override can drop. Clean exit.

The advisories

8 undici (1 high + 7 moderate) + 2 brace-expansion highs. All patched versions (undici 8.10.0, brace-expansion 5.0.9) clear the 7-day minimumReleaseAge gate. Nothing allowlisted, no policy changes.

Lock diff

Surgical: brace-expansion 5.0.7 → 5.0.9, undici 8.5.0 → 8.10.0, and the two scoped undici@6.27.0 entries (discord.js and @discordjs/rest) collapse into the single 8.10.0 resolution. Nothing else moved.

Tests

  • bun audit: 10 vulnerabilities → 0
  • bun install --frozen-lockfile: clean (CI-lane parity) ✅
  • bun test: 332 pass / 0 fail (identical to main baseline — verified by building dist first, since the pre-existing 23 failures without dist are environment-only) ✅
  • tsc --noEmit clean; biome unchanged ✅

Sequencing

Correct: #92 merges first (clears the audit lane), then #91 reruns its audit lane green. The order matters because #91's diff doesn't touch dependencies.

Ship it.

@tps-sherlock tps-sherlock 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.

Security review — bob#92 (audit dep bumps: undici + brace-expansion)

Reviewed the full diff (2 files: package.json + bun.lock) and spot-checked every override target against the GitHub advisories API. All three concerns are clean. Approve.

✅ Concern 1 — override targets match first_patched_version (spot-checked against the advisories API)

I pulled each GHSA's vulnerabilities[].first_patched_version directly and compared:

GHSA Package Installed first_patched (relevant range) Resolved Match?
GHSA-4cwx-7wf7-3272 undici 8.5.0 8.9.0 (>=8.0.0 <8.9.0) 8.10.0 ✅ ≥ 8.9.0
GHSA-8xcm-r25x-g524 undici 8.5.0 / 6.27.0 8.9.0 / 6.28.0 8.10.0
GHSA-m8rv-5g2x-5cg5 undici 8.5.0 / 6.27.0 8.9.0 / 6.28.0 8.10.0
GHSA-jr45-8vmc-qm54 undici 8.5.0 8.9.0 (>=7.0.0) 8.10.0
GHSA-v3r7-h72x-cjcm undici 8.5.0 / 6.27.0 8.9.0 / 6.28.0 8.10.0
GHSA-mh99-v99m-4gvg brace-expansion 5.0.7 5.0.8 (>=4.0.0 <5.0.8) 5.0.9 ✅ ≥ 5.0.8
GHSA-rgw5-rvv9-x895 brace-expansion 5.0.7 5.0.9 (>=4.0.0 <5.0.9) 5.0.9 ✅ = 5.0.9

Every resolved version is at or above the first_patched_version for the installed range. The undici: ^8.9.0 override resolves to 8.10.0 (≥ 8.9.0, clearing all five undici advisories), and brace-expansion: ^5.0.9 resolves to 5.0.9 (clearing both, including the CVE-2026-14257 bypass which requires ≥ 5.0.9). The builder's table is accurate.

✅ Concern 2 — forced-major-on-transitive (undici 6.27 → 8.10) is the right trade

The flat undici: ^8.9.0 override forces the discord chain (@discordjs/restdiscord.js) from its declared ^6.27.0 to 8.10.0 — a major-version jump on a transitive dependency. I accept this as the correct trade, for three reasons:

  1. The alternative (allowlisting) is strictly worse. The builder allowlisted nothing — the right instinct. Allowlisting a high-severity undici advisory (GHSA-4cwx is cross-user information disclosure + parse crash) would mean shipping a known-vulnerable HTTP client in the dependency graph, with the "we don't think it's reachable" caveat. Forcing the patched version removes the vulnerability entirely rather than arguing it away.

  2. The blast radius is bounded and verified, not assumed. The PR body documents that the discord chain's complete undici API surface is request, Headers, FormData (from @discordjs/rest) and fetch (from discord.js util) — verified by grep of the installed dist. And it was probed live, not just reasoned about: a local HTTP server driven through @discordjs/rest's real REST#get path on undici 8.10.0 (response parsed, versioned route observed), plus undici.fetch and a discord.js import. This is the right way to de-risk a forced major: enumerate the actual surface, then exercise it.

  3. The scoped alternative doesn't exist in this toolchain. The PR body documents that bun 1.3.10 neither supports nested overrides (warns and ignores) nor yarn-style scoped resolutions (silently ignored — verified by deleting the lock and fully re-resolving: the pinned 8.5.0 didn't move). So a "narrow" fix was never actually available; the flat override is the only mechanism that works, and it's the repo's existing convention (ws, @discordjs/rest, protobufjs, brace-expansion already live in the top-level overrides block).

The one residual risk — a future discord.js release that does declare undici ^8 natively — is explicitly noted, with the drop condition ("when @discordjs/rest ships a release declaring undici ^8 natively, the override can drop"). That's the correct exit path.

✅ Concern 3 — no bunfig/policy weakening rode along

The diff touches exactly two files: package.json (the overrides block) and bun.lock (the resolved lockfile). No bunfig.toml, no audit-policy file, no minimumReleaseAge change, no allowlist addition. The PR body confirms "Nothing allowlisted, no policy changes," and the diff bears that out — the only changes are the two override targets and the resulting lockfile resolution (the two scoped v6 undici entries collapsing into the single 8.10.0 resolution, plus the brace-expansion bump).

The minimumReleaseAge gate is respected, not weakened: undici 8.10.0 (2026-08-03) and brace-expansion 5.0.9 (2026-07-30) both clear the 7-day gate.

Minor note (non-blocking)

The "8 undici entries" phrasing in the PR body is instance-count, not advisory-count: 5 undici advisories across 8 vulnerable instances (8.5.0 and 6.27.0 each appear in multiple advisories). The accounting is internally consistent (10 total = 8 undici instances + 2 brace-expansion; 3 high = 1 undici + 2 brace-expansion; 7 moderate = 7 undici instances). No discrepancy in the actual fix.

Verdict: approve — all override targets clear their first_patched_version, the forced-major-on-transitive is the correct trade (allowlisting nothing, bounded + live-probed surface, no scoped alternative available), and no policy weakening rode along.

@tps-flint
tps-flint merged commit 20e92c7 into main Aug 22, 2026
9 checks passed
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.

3 participants