Security: resolve npm audit high-severity advisories (esbuild/vite, cookie) failing the CI audit gate #817
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
The CI step "Security audit (no dev deps)" (
npm audit --audit-level=high --omit=dev,.gitea/workflows/ci.yml:32-33) fails with exit 1. This is repo-wide and not caused by any one PR —frontend/package-lock.jsonwas last changed onmainatfab2930c(2026-06-03), and the failure is driven by newly-published advisories landing against already-pinned versions.mainitself is red on this gate today; it surfaced on the #774 PR run but #774 touched zero frontend files. Net effect: the audit gate blocks every PR until remediated.Current state (verified on
frontend/package.json)@sveltejs/kit^2.60.1·vite^7.3.3·@sveltejs/vite-plugin-svelte^6.2.1·@sentry/sveltekit^10.53.1·svelte^5.43.8overridesblock exists.esbuildresolves to0.27.7(transitively viavite).Advisories reported (verified by running the exact gate command — 7 findings: 4 high, 3 low)
High (4 — these fail
--audit-level=high):esbuild— Missing binary integrity verification in Deno module enables RCE viaNPM_CONFIG_REGISTRY— GHSA-gv7w-rqvm-qjhresbuild— Arbitrary file read when running the dev server on Windows — GHSA-g7r4-m6w7-qqqresbuild 0.17.0 - 0.28.0(inclusive) — so installed0.27.7is affected; first fixed release isesbuild@0.28.1. Pulled in transitively viavite→@sveltejs/vite-plugin-svelte.Low (3):
cookie <0.7.0— accepts out-of-bounds characters in name/path/domain — GHSA-pxg6-pf52-xh8x — via@sveltejs/kit, reaching the prod audit tree through@sentry/sveltekit's peer dependency. Below thehighgate threshold (does not block CI), butcookie@0.7.0is a drop-in, so clear it in the same pass.Exploitability note (honest prioritisation — confirmed accurate in review)
Both high findings are build/dev-time in this project's context: the esbuild dev-server file-read is Windows-only and not exposed in CI/prod; the Deno-module RCE requires a Deno toolchain we don't use. Nothing vulnerable ships to end users at runtime. The urgency is about unblocking the CI gate on all PRs, not a live production exposure — hence P1-high (workflow friction), not P0.
Why the obvious paths don't work
npm audit fix --force. It wants@sveltejs/kit@0.0.30(a nonsensical downgrade that reintroduces years of patched framework CVEs) andvite@8.0.16(a major breaking bump). It would wreck the toolchain.vite@7minor bump cannot help (verified dead-end). Novite@7.xup to the current7.3.5accepts a patched esbuild — they all pinesbuild: "^0.27.0"(<0.28.0), and the fix only exists at0.28.1. There is no patched esbuild within^0.27.Primary fix — Option 1:
overridespinsAdd to
frontend/package.json:Pin
esbuildexact (no caret) so a future0.29.xcan't silently float in on the nextnpm installand re-break vite — let Renovate propose bumps explicitly.Known risk (must be validated, not assumed): this forces
esbuild@0.28.1outsidevite@7.3.3's declared^0.27.0range. esbuild is pre-1.0; minor bumps can break. The override is only acceptable if bothnpm run buildand anpm run devboot succeed. If either breaks → escalate (below).Then regenerate the lockfile deterministically and commit both files in one atomic commit:
(The CI cache key is
hashFiles('frontend/package-lock.json'), so the lockfile change cleanly invalidates the node_modules cache.)Fallback — Option 2 (escalate only if Option 1 breaks the build/dev server): Vite 8 migration
This is not "bump vite" — it's a coordinated multi-package migration, because
@sveltejs/vite-plugin-svelte@6peersvite: ^6.3.0 || ^7.0.0and will not accept vite@8:vite→^8@sveltejs/vite-plugin-svelte→^7(peer-requiresvite ^8andsvelte ^5.46.4)svelte→≥5.46.4@sveltejs/kitresolves to2.65(its peers already accept vite^8)Spin this out into its own issue + a short ADR in
docs/adr/if it's needed. Its verification is heavier than Option 1 (see below).Acceptance criteria
cd frontend && npm audit --audit-level=high --omit=devexits0with0 highin the report (the exact command the CI step runs).package.jsonoverridesand the regeneratedpackage-lock.jsonare committed together.npm run buildsucceeds andnpm run devboots and serves one route without an esbuild transform error.Verification checklist (paste into the PR)
The last line is what actually de-risks Option 1 — do not drop it.
Out of scope
escelate if this does not work. I think we need a new issue to correctly setup renovate
marcel referenced this issue2026-06-13 00:10:39 +02:00
marcel referenced this issue2026-06-13 00:11:03 +02:00
Implemented — Option 1 (
overrides), PR #819Option 1 held; no escalation to the Vite 8 migration was needed. Build and dev-server both succeed with the forced
esbuild@0.28.1.Change (
frontend/package.json+ regeneratedpackage-lock.json, one atomic commitd11378c2):esbuildexact-pinned (no caret) — Renovate proposes future bumps explicitly.cookiefloats to1.1.1(satisfies>=0.7.0), clearing the lowcookiefinding in the prod tree.patch-package/postinstalland the@vitest/browser-playwright@4.1.6pin (ADR-012) untouched.Verification (red→green proof):
1, 7 vulns (4 high, 3 low).npm audit --audit-level=high --omit=dev→ exit 0, "found 0 vulnerabilities".npm ls esbuild→esbuild@0.28.1 overridden.npm run build→ adapter-node✔ done+ postbuild pdfjs-wasm assert pass.npm run lint→ clean.npm run check→ 801 errors / 38 warnings (matches known baseline; 0 in the files touched).npm run dev→ boots,/hilfe/transkriptionrenders 200, no esbuild transform error → killed.npm run test→ deferred to CI (full Vitest browser sweep OOMs this dev box; change touches only dep versions, zero source).Follow-up: prevention/early-warning (nightly audit gate + Renovate vulnerability surfacing) remains for its own issue, per the decision above — I have not opened it yet; say the word and I'll spin it up with a proper Renovate spec.
Review at PR #819.