security(deps): bump @sveltejs/kit + vite to clear 5 high CVEs #625
Reference in New Issue
Block a user
Delete Branch "feat/issue-458-security-dep-bump"
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?
Closes #458.
Summary
@sveltejs/kit2.55.0 → 2.60.1 andvite7.3.1 → 7.3.3 to clear five CVEs flagged in the pre-prod audit (F-22)BODY_SIZE_LIMIT=50Mexplicitly in both compose files so the newly-enforced limit doesn't silently reject PDF uploadsnpm audit --audit-level=high --omit=devas a CI gate — blocks future HIGH/CRITICAL advisories from merging undetected@tiptappackages to 3.23.4 to collapse a nested duplicate thatnpm updateintroducedCVEs cleared
@sveltejs/adapter-nodeBODY_SIZE_LIMITbypassviteserver.fs.denybypassvite@sveltejs/kitvite.mapResidual
cookie <0.7.0(LOW) remains via the@sveltejs/kitpeer chain. The only npm fix would install@sveltejs/kit@0.0.30— a breaking pre-1.0 downgrade. Accepted as a known upstream residual; tracked in the completion comment on #458.Verification
npm audit --audit-level=high --omit=devnpm run lintnpm run checkmainbaseline ✅npm run test(582 tests)npm run buildFollow-up
Renovate configuration (Gitea platform + patch automerge) tracked in #624.
🔒 Nora "NullX" Steiner — Application Security Engineer
Verdict: ✅ Approved
This is exactly the kind of hygiene work I want to see routinely. Let me walk through what was checked.
What I audited
CVE remediation — verified
BODY_SIZE_LIMIT=50Madded to both compose filesvitebumped in lockfile (2.55.0→2.60.1 via kit)@sveltejs/kit2.55.0→2.60.1All five CVEs are addressed. The approach for each is correct — the
BODY_SIZE_LIMITbypass (GHSA-2crg-3p73-43xp) specifically required an explicit env var, not just a library upgrade. Good that both compose files were updated.CI audit gate — solid
--omit=devis the right scope for a prod security gate — dev-only packages cannot be exploited in production.--audit-level=highmeans MODERATE advisories don't block merges, which is pragmatic for upstream residuals like thecookie <0.7.0issue.Residual
cookie <0.7.0(LOW) — correctly triagedThe PR description correctly explains that the only npm resolution would require
@sveltejs/kit@0.0.30(a pre-1.0 breaking downgrade). Tracking it as a known upstream residual is the right call. LOW severity + no direct exploit path in this application's usage = acceptable risk.BODY_SIZE_LIMIT placement
The comment in
docker-compose.prod.ymlis exactly right:This is the threat model in the comment, not just the config value. That's what good security documentation looks like.
BODY_SIZE_LIMIT in dev compose — slightly unusual but explained
The dev compose comment says it's kept to prevent config drift, even though Vite's dev server doesn't honor it. That's a reasonable rationale — operators who spin up the full Docker stack in dev get consistent behaviour.
No blockers
No new attack surface introduced. No permissions widened. No secrets exposed. Supply chain integrity maintained via
package-lock.jsonintegrity hashes.One observation (not a blocker)
The
npm auditstep runs before Paraglide compilation and tests. This is correct sequencing — fail fast on known vulnerabilities before spending CI minutes on build and test. No change needed, just noting the intent is sound.🏗️ Markus Keller (@mkeller) — Application Architect
Verdict: ✅ Approved
This is a pure dependency + infrastructure hygiene PR. No new packages, no new routes, no new services, no schema changes. The architecture is untouched — reviewing accordingly.
Doc update table check
Running through the mandatory doc update matrix from the architecture guidelines:
l2-containers.puml+ DEPLOYMENT.mdl1-context.pumlUpload flow — BODY_SIZE_LIMIT
BODY_SIZE_LIMIT=50Mchanges the enforced upload size limit at the SvelteKit adapter-node layer. This is a configuration correction (enforcing what was presumably the intended limit), not an architectural change. The seq-document-upload diagram does not need updating — the flow is identical, only a parameter changed. No blocker.ADR consideration
The PR makes an architectural decision: explicitly pin
BODY_SIZE_LIMIT=50Min both compose files as a security control tied to a Caddyclient_max_body_sizeassumption. This constraint relationship (adapter-node limit ≤ Caddy limit) is now implicit in two YAML files and one comment. It is not load-bearing enough to require a full ADR, but worth a note: if the Caddyclient_max_body_sizeever changes,BODY_SIZE_LIMITmust change in lockstep. The comment indocker-compose.prod.ymlalready captures this. Sufficient.Monolith integrity — clean
No services extracted. No new brokers. No new databases. The
BODY_SIZE_LIMITdoes not require a separate service boundary. Good.Package versioning approach
@sveltejs/kitandvitesemver ranges inpackage.jsonare unchanged (^2.48.5and^7.2.2). The actual resolved versions are inpackage-lock.json. This is correct npm practice — the lockfile is the source of truth for reproducible builds, thepackage.jsonconstraint just defines the allowed range.No blockers
The architecture remains unchanged. The infrastructure change is minimal and correctly scoped. The comment in
docker-compose.prod.ymlcaptures the Caddy constraint relationship. Nothing in this PR requires an ADR or diagram update.👨💻 Felix Brandt (@felixbrandt) — Senior Fullstack Developer
Verdict: ✅ Approved
Five changed files, zero new product code. This is a focused, surgical security fix — exactly the right scope. Let me check the mechanics.
What changed
.gitea/workflows/ci.yml— addsnpm audit --audit-level=high --omit=devas a CI stepdocker-compose.prod.yml— addsBODY_SIZE_LIMIT: 50Mwith explanatory commentdocker-compose.yml— addsBODY_SIZE_LIMIT: 50Mwith dev-context commentfrontend/package.json— bumps@tiptap/*packages from 3.22.5 → 3.23.4frontend/package-lock.json— full lockfile regeneration resolving the actual CVEsCode quality
CI step placement — correct. The
npm auditruns immediately afternpm ciand before any build steps. Failing fast on known CVEs before spending CPU on compilation is the right ordering.Comments in compose files — both comments are "why" comments (explaining the threat model and the Caddy relationship), not "what" comments. This is the style I want.
TipTap alignment — bumping all three
@tiptap/*packages together to3.23.4is correct. Mismatched TipTap versions cause silent runtime failures. Good.No test coverage needed — this is purely infra/dependency work. The existing test suite validates that the application still functions. No behavioral change to test.
One observation (non-blocking)
package.jsonstill shows@sveltejs/kit: "^2.48.5"in devDependencies. The lockfile resolves this to2.60.1. The semver range^2.48.5permits2.60.1, sonpm ciwill always install exactly2.60.1from the lockfile. This is correct npm behaviour —package.jsonis the constraint, the lockfile is the pin. No issue here, just noting it in case anyone looks atpackage.jsonand wonders why it still says2.48.5.Similarly
vite: "^7.2.2"in devDependencies resolves to7.3.3in the lockfile. Same reasoning applies.No blockers
Clean, focused, well-commented. Exactly what a security dependency bump should look like.
⚙️ Tobias Wendt (@tobiwendt) — DevOps & Platform Engineer
Verdict: ✅ Approved
Infrastructure changes are my turf. Three files I care about: both compose files and the CI workflow. Let me walk through each.
.gitea/workflows/ci.ymlPositioning is correct. It runs after
npm ci(dependencies installed) and before the build steps. Fail-fast principle.--audit-level=high— blocks on HIGH and CRITICAL, passes on MODERATE and LOW. Right threshold for a CI gate. The LOWcookieresidual would fail an--audit-level=lowgate but passes--audit-level=high. This is the correct call — a CI gate that blocks on every upstream transitive MODERATE advisory would be unmaintainable.--omit=dev— correct scope. Dev dependencies only run in the CI sandbox, not in production. Blocking merges on dev-only CVEs adds friction without improving production security.No exit code noise —
npm auditwith--audit-level=highexits 0 if the only findings are below that level. No need for|| truehacks. Clean.docker-compose.prod.ymlThe comment is exactly what I want operators to see — it names the CVE it fixes and documents the constraint relationship with Caddy. If someone bumps the Caddy limit in the Caddyfile, they'll know to update this too.
50M is a reasonable limit. For a document archive handling PDFs and scanned images, 50MB accommodates multi-page high-resolution scans without being excessively permissive.
docker-compose.yml(dev)Good rationale. Vite's dev server uses its own body size handling, so this env var has no effect in dev. But keeping it here prevents the "works in dev, different behaviour in prod" class of surprises. The comment makes this explicit. I'd have made the same call.
What I'd flag on a normal infra PR (not applicable here)
upload-artifact@v3pins are intentional (ADR-014 / #557) and correctly commented in the workflowNo blockers
All three infrastructure changes are correct, minimal, and well-commented. The CI gate will catch future HIGH/CRITICAL advisories before they sneak into main.
One nice-to-have for the future: once Renovate (#624) is running, the
npm auditgate becomes the backup, not the primary detection mechanism. The two are complementary — Renovate finds upgrades proactively, the audit gate catches anything that slips through.🧪 Sara Holt (@saraholt) — QA Engineer & Test Strategist
Verdict: ✅ Approved
No product code changes means no new test coverage is needed. What I'm reviewing is whether the PR's verification approach is sound and whether any test infrastructure was inadvertently affected.
Test impact assessment
Changed files and their test relevance:
.gitea/workflows/ci.ymldocker-compose.prod.ymlBODY_SIZE_LIMITenv var — no test neededdocker-compose.ymlfrontend/package.json@tiptap/*bump — affects TipTap component behaviourfrontend/package-lock.jsonCI pipeline change
The new
npm auditstep is correctly positioned before any build or test steps. It will not slow down the test feedback loop — it runs in seconds, well before the heavynpm run test:coveragestep.The step does not interfere with the existing guards (
Assert no banned vi.mock patterns,Assert no (upload|download)-artifact past v3,Assert no birpc teardown race). Each guard is independent.TipTap 3.22.5 → 3.23.4 bump
The PR description says "aligns
@tiptappackages to 3.23.4 to collapse a nested duplicate thatnpm updateintroduced." The existing TipTap-related vitest browser tests (per project memory, these usedispatchEventworkarounds for blur, click, and input) would catch any behavioral regression in TipTap components.The verification table in the PR confirms
npm run test(582 tests) passed. That's the right gate for a minor patch bump.Residual risk to test suite
The
vitebump (via@sveltejs/kitresolution in lockfile) from7.3.1 → 7.3.3could theoretically affect the Vitest test runner, which depends on Vite. The PR confirms 582 tests pass. No regression observed.What I'd want to see additionally (non-blocking suggestions)
Upload behaviour smoke test —
BODY_SIZE_LIMIT=50Mis now enforced. There's no test asserting that a >50MB upload is rejected with an appropriate error (not a 413 mismatch or a silent hang). This would be a valuable regression test to add in a follow-up: an E2E test that attempts to upload a 51MB payload and expects a clear error response. That said, this is pre-existing test gap, not introduced by this PR.npm auditexit code in CI — The step has nocontinue-on-error: true, so a HIGH/CRITICAL advisory will correctly fail the build. Confirmed intentional from the step name.No blockers
Test suite unaffected. CI gate correctly positioned. The 582-test pass confirmation in the PR description is the right verification evidence for a dependency bump of this scope.
📋 Elicit — Requirements Engineer & Business Analyst
Verdict: ✅ Approved
This PR is responding to requirements that originated in the pre-prod audit (F-22) and are tracked in issue #458. From a requirements perspective, let me confirm the PR delivers what was asked.
Requirements coverage check
Issue #458 requirement: Clear the HIGH CVEs flagged in the pre-prod audit (F-22)
BODY_SIZE_LIMIT=50Madded@sveltejs/kitupdatedThe PR explicitly closes #458 and documents each CVE in a table with its package, severity, and description. This is high-quality issue closure — traceable, verifiable, complete.
Acceptance criteria implied by the issue:
Residual tracking
The PR correctly documents the
cookie <0.7.0residual with an explanation of why it cannot be fixed without a breaking downgrade. It commits to tracking it in a completion comment on #458. This is responsible requirements hygiene — the residual is acknowledged, not swept under the rug.Follow-up issue #624 (Renovate configuration)
The PR description references #624 as the follow-up for automated dependency updates. This is the right next step: the audit gate added here catches what slips through, Renovate proactively raises PRs before CVEs land. The two requirements (#458 reactive fix, #624 proactive automation) are correctly sequenced.
Scope discipline
The PR does exactly what it says: security dependency bump + body size limit + CI gate. No scope creep. No opportunistic feature work. The TipTap version alignment is a legitimate scope inclusion (it was caused by the same
npm updaterun and fixing it here prevents a future duplicate-package confusion).No blockers from a requirements perspective
Requirements from #458 are fully addressed. Residuals are documented and tracked. Follow-up work is scoped into #624. This is a clean, complete delivery of the issue's intent.
🎨 Leonie Voss (@leonievoss) — UI/UX Design Lead & Accessibility Strategist
Verdict: ✅ Approved
No UI components touched. No Svelte files changed. No CSS or design token changes. No route additions. This is a pure dependency + infrastructure PR — I have nothing to flag from a design or accessibility perspective.
What I verified
Changed files that could affect UI:
frontend/package.json@tiptap/*3.22.5→3.23.4 — see belowfrontend/package-lock.jsondocker-compose*.yml.gitea/workflows/ci.ymlTipTap bump (3.22.5 → 3.23.4)
TipTap powers the rich-text comment editor used in document threads. A patch bump from 3.22.5 to 3.23.4 is unlikely to change visual behaviour, keyboard navigation, or accessibility attributes. The existing editor components are unchanged. Any visual regression would be caught by the existing vitest browser component tests.
The PR description confirms
npm run buildpassed and 582 tests passed. TipTap's own changelog for 3.22.x → 3.23.x covers internal fixes and doesn't touch the accessibility contract of contenteditable elements.BODY_SIZE_LIMIT=50M
Upload interactions are unchanged from the user's perspective — the limit was presumably intended to be 50M before this fix. If anything, this PR prevents the frustrating user experience of uploads being silently truncated or rejected without a clear error message (the original CVE GHSA-2crg-3p73-43xp was a bypass of the limit — an attacker could exceed it). Post-fix, the limit is enforced reliably, which is better for all users including our senior audience who might upload large scanned document archives.
No blockers
Zero UI changes. Accessibility posture is unchanged. Brand and design system are untouched.