Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,27 @@ Keep them in lockstep when bumping. Raising `.nvmrc` alone makes CI validate aga

### Audit advisories

`bun audit` is the source of truth for dependency advisories. State as of 2026-08-27 — 4 advisories, all dev-only:
`bun audit` is the source of truth for dependency advisories. State as of 2026-10-28 — 10 advisories, none in the client bundle or server runtime. Nine are dev-only via `@lhci/cli`; one is build-only.

**Resolved by an `overrides` entry:**

- **sharp `<0.35.0`** (GHSA-f88m-g3jw-g9cj, high — inherited libvips CVE-2026-33327 / -33328 / -35590 / -35591). `[email protected]` already asks for `sharp@^0.35.3`, but `[email protected]` declares `sharp@^0.34.5`, a range that cannot reach 0.35.x — so the tree carried a vulnerable second copy at 0.34.5. Resolved via `overrides.sharp = "^0.35.3"`, which pulls velite onto the patched line and dedupes to a single copy. Crossing 0.34 → 0.35 is a breaking bump on sharp's 0.x line; verified safe here because velite's image pipeline runs during `bun run build` and the build passes. Drop the override once velite ships a release declaring `sharp@^0.35.0` or later — 0.4.0 did not, so this is likely to persist for a while.
- **sharp `<0.35.5`** (GHSA-wq5f-xc86-pv6w, high — librsvg CVE-2026-96889; also GHSA-rgj7-g3m4-5g8c `<0.35.4` and GHSA-f88m-g3jw-g9cj `<0.35.0`). `[email protected]` asks for `sharp@^0.35.5`, but `[email protected]` declares `sharp@^0.34.5`, a range that cannot reach 0.35.x, so the tree would carry a vulnerable second copy. `overrides.sharp = "^0.35.5"` pulls velite onto the patched line and dedupes to one copy. Crossing 0.34 → 0.35 is a breaking bump on sharp's 0.x line; verified safe because velite's image pipeline runs during `bun run build` and the build passes. Drop the override once velite ships a release declaring `sharp@^0.35.5` or later — 0.4.0 is still the latest.

**Accepted — fix exists but is inside the 14-day cooldown.** These clear on their own: Renovate's `lockFileMaintenance` (or a manual `bun update`) picks up the patched version once it is 14 days old, because each parent's range already admits it.

- **body-parser `<1.20.9`** (GHSA-27r3-jxmh-p828, high DoS via trailing bytes after a compressed body) and **qs `<=6.16.0`** (GHSA-6pq8-jhm2-2vcw, moderate DoS in `stringify` with `arrayFormat: 'comma'`). Path: `@lhci/cli > express > body-parser > qs`. Express backs `lhci server`, which we never run (`lighthouserc.cjs` uploads to temporary public storage), so no request ever reaches body-parser. 1.20.9 clears the window on 2026-11-06; qs 6.16.2 on 2026-11-11. Drop these entries once `bun audit` stops reporting them.
- **postcss-selector-parser `<6.1.5`** (GHSA-rj75-hqrm-r3gf, moderate quadratic-time parsing). Path: `@tailwindcss/typography > [email protected]` (an exact pin, so lockfile maintenance cannot fix it). Build-time only: it parses the selectors in our own stylesheets, never user input. Once 6.1.5 is 14 days old (2026-11-03), add `overrides["postcss-selector-parser"] = "^6.1.5"` (same major) unless `@tailwindcss/typography` has shipped a release that bumps it.

**Accepted — upstream-blocked, every path is via `@lhci/[email protected]`, which is dev-only and runs in CI against its own controlled inputs:**

- **extract-zip `<=2.0.1`** (GHSA-jmr9-qjv8-65gv, high unvalidated symlink path traversal). Path: `@lhci/cli > lighthouse > puppeteer-core > @puppeteer/browsers > extract-zip`. No patched version exists — 2.0.1 is the latest publish, so there is nothing to override to. The archives extracted are Chrome builds fetched by puppeteer from Google's own CDN, not attacker-supplied. Drop this entry when `extract-zip` ships a fix or `lighthouse` moves off it.
- **extract-zip `<=2.0.1`** (GHSA-jmr9-qjv8-65gv, high unvalidated symlink path traversal; GHSA-7pqw-9j4j-h8q3, high arbitrary file write via symlink entries). Path: `@lhci/cli > lighthouse > puppeteer-core > @puppeteer/browsers > extract-zip`. No patched version exists — 2.0.1 is the latest publish, so there is nothing to override to. The archives extracted are Chrome builds fetched by puppeteer from Google's own CDN, not attacker-supplied. Drop this entry when `extract-zip` ships a fix or `lighthouse` moves off it.
- **zod `<4.6.6`** (GHSA-mrhx-c7xc-m3w5, high memory exhaustion on oversized constrained collections). Path: `@lhci/cli > lighthouse > puppeteer-core > chromium-bidi > [email protected]`. No 3.x fix exists, and chromium-bidi declares `zod@^3.24.1`, so an override would force a 3 → 4 major under a library we do not control. zod only validates protocol messages from the local Chrome that lhci launches. Drop this entry when chromium-bidi moves to zod 4 or a 3.x fix ships.
- **basic-ftp `<=6.2.0`** (GHSA-c475-qrg2-pj4r, high quadratic-time directory-listing parser). Path: `@lhci/cli > proxy-agent > pac-proxy-agent > get-uri > [email protected]`. Only the 6.x line is patched and get-uri declares `basic-ftp@^5.0.2`, so the fix needs a 5 → 6 major. basic-ftp runs only for `ftp://` proxy or PAC URLs, and CI configures none. Drop this entry when get-uri moves to basic-ftp 6.
- **tmp `<0.2.6`** (GHSA-ph9p-34f9-6g65, high path traversal via unsanitized prefix/postfix) and **tmp `<=0.2.3`** (GHSA-52f5-9888-hmc6, low symlink write via the `dir` param). `@lhci/cli` pulls `[email protected]` and `[email protected]`. Overriding to `^0.2.6` crosses tmp's 0.1 → 0.2 API break (the sync/callback surface changed) inside a tool we cannot test beyond running it, so the override is not worth the risk for a CI-only dev dep. Neither traversal scenario applies: nothing passes user input to `tmp`'s prefix, postfix, or `dir`. Drop this entry when `@lhci/cli` ships a release with patched transitives.
- **uuid `<11.1.1`** (GHSA-w5hq-g745-h8pq, moderate missing buffer bounds in v3/v5/v6 when `buf` is provided). Now a single path, `@lhci/cli > [email protected]` — the former `resend > svix > uuid` path cleared when resend went to 6.19.0, so this is no longer a production concern. The vulnerable code (v3/v5/v6 called with an explicit `buf`) is not reached. Drop this entry when `@lhci/cli` bumps uuid.
- **uuid `<11.1.1`** (GHSA-w5hq-g745-h8pq, moderate missing buffer bounds in v3/v5/v6 when `buf` is provided). Single path, `@lhci/cli > [email protected]`. The vulnerable code (v3/v5/v6 called with an explicit `buf`) is not reached. Drop this entry when `@lhci/cli` bumps uuid.

**Cooldown exemptions.** `bunfig.toml` → `install.minimumReleaseAgeExcludes` lists `next`, its `@next/*` platform packages, `react` and `react-dom`. Next 16.4.1 fixes two critical RCEs (GHSA-2464-fhr4-w9xw, GHSA-673q-mjm6-r5xr) and a high DoS (GHSA-p3m5-59mp-jv5r), but was 13 days old when adopted. React 19.3.1 hardens the Server Components transport. An exemption covers every future version of the package, not only the one adopted, so remove the whole list after 2026-10-29, when both versions are past the window.

**Cleared, for the record:** the `postcss` override (GHSA-qx2v-qp2m-jg93) is gone — `[email protected]` pins `[email protected]` exactly and `@tailwindcss/[email protected]` resolves `^8.5.16` to 8.5.26, both well past the 8.5.10 floor, so the old `8.5.13` pin had become a *downgrade* of next's own exact pin. Two postcss copies now coexist because next pins exactly; deduping them would mean forcing next off that pin, and postcss is build-time only (never in the client bundle), so the duplicate is left alone. The `mdast-util-to-hast` override (GHSA-4fh9-h7wg-q85m) is also gone — its parents still declare `^13.0.0`, but that range now resolves to 13.2.1 on its own, making the floor guard a no-op.
**Held back on purpose:** `@types/node` stays on `^24` to match the deployable runtime (see "Node version"); `renovate.json` caps it with `allowedVersions: "<25"` so Renovate stops opening 25.x / 26.x PRs.

The `audit` job in `.github/workflows/ci.yml` runs a bare `bun audit` and never fails CI; the advisories above (including the two upstream-blocked ones) show in its job summary until their removal triggers land. Merge blocking on advisories is `dependency-review`'s job.
The `audit` job in `.github/workflows/ci.yml` runs a bare `bun audit` and never fails CI; the advisories above show in its job summary until their removal triggers land. Merge blocking on advisories is `dependency-review`'s job.
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.8/schema.json",
"$schema": "https://biomejs.dev/schemas/2.5.15/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
Loading
Loading