chore(deps): update dependency vitest to v4.1.11 [security] #57
No reviewers
Labels
No labels
idea
points
1
points
13
points
2
points
3
points
5
points
8
priority
p0
priority
p1
priority
p2
priority
p3
state
blocked
state
done
state
in-progress
state
ready
state
review
state
triage
status
declined
status
in-progress
status
planned
status
proposed
status
shipped
status
under-review
type
bug
type
epic
type
feature
type
spike
type
story
type
task
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
tti/tti-ux!57
Loading…
Reference in a new issue
No description provided.
Delete branch "renovate/npm-vitest-vulnerability"
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?
This PR contains the following updates:
^4.1.10→^4.1.114.1.10→4.1.11Vitest: Path Traversal / Arbitrary File Read via @vitest/mocker Redirect Mock
CVE-2026-84373 / GHSA-82fw-gwwq-j7x9
More information
Details
Summary
@vitest/mockerregisters a redirect mock's target path without validating itagainst the dev server's file-serving allowlist. An attacker who can reach the
dev server's WebSocket can register a redirect mock pointing outside the project
root; when the mocked module is requested, the plugin's
loadhook returnsreadFile(<attacker path>)as the module source, disclosing local files.This is exploitable without authentication only through the public
mockerPlugin/ standaloneinterceptorPluginexports (used by third-party devservers), which register the handler on Vite's unauthenticated HMR socket.
Vitest's own browser mode registers mocks over a token-authenticated RPC and
is not remotely reachable by default (see Scope).
Affected code
packages/mocker/src/node/interceptorPlugin.ts.The
loadhook is the file-read sink:mock.redirectis derived from client input at registration time with noboundary check:
There is no
server.fs.allow/server.fs.denycheck and no assertion that theresolved path stays within the project root.
Registration paths and trust boundaries
mockerPlugin/interceptorPlugin(unauthenticated). InconfigureServer, the plugin registersserver.ws.on('vitest:interceptor:register', …)on Vite's HMR WebSocket. That socket performs no token, Origin, or same-origin
check, so any client that can reach it can register a redirect mock. This is
the path the "unauthenticated" impact applies to.
(
registerMock), which sits behind a per-run token (isValidApiRequest, arandom
api.token). The interceptor'sconfigureServersocket is not used forregistration here (in v5 it does not run at all, as the plugin is injected per
environment). The same missing boundary check exists on the authenticated RPC
path, but reaching it requires the token, so it is not a remote-unauthenticated
read.
Path handling
new URL(redirect).pathnamecombined withjoin(root, pathname)does notconfine reads to the root:
file:,http:) are normalized by WHATWG URL,so
..segments are collapsed and the result stays under the root. Payloads ofthe form
file:///../../etc/passwddo not escape...inpathname, sojoin(root, "../../…/etc/passwd")resolves outside the root and reads anarbitrary file.
Even without escaping the root, the missing
server.fscheck allows reading anyin-root file the dev server would otherwise refuse to serve (for example an
in-root
.envor source that is denied byserver.fs.deny).Scope / preconditions
localhostbydefault and is not reachable from the network unless the developer exposes it
(
server.host/0.0.0.0, a LAN bind, or a proxy).and CORS protections entirely and can both register the mock and read the
response.
by Vite defaults: the default CORS origin allowlist is limited to
localhostorigins, and
server.allowedHostsblocks DNS-rebinding, so a cross-origin pagecannot read the file contents back.
Impact
Disclosure of local files readable by the dev-server process (source, in-root
.env/secrets, and, via the opaque-scheme payload, files outside the projectroot). No integrity or availability impact.
Affected versions
Present since
@vitest/mockerwas introduced.@vitest/mocker>= 2.1.0 (shipped invitestand@vitest/browser>= 2.1.0), through 4.1.x and the 5.0.0 pre-releases.maintained and are not planned to receive the fix.
Fix
Validate the resolved redirect target against Vite's file-serving allowlist
(
isFileLoadingAllowed) before registering it, at every registration site, andstop registering the interceptor WebSocket events in Vitest's browser mode
(mocks there flow through the authenticated RPC).
Severity
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:NReferences
This data is provided by OSV and the GitHub Advisory Database (CC-BY 4.0).
Configuration
📅 Schedule: (UTC)
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about these updates again.
This PR has been generated by Mend Renovate CLI.
🔧 Security-gate fix map
The gate failed on these dependency findings — fastest path to green for each:
@tiptap/corenpm update core --package-lock-onlyjs-yamlnpm update js-yaml --package-lock-onlysharpnpm update sharp --package-lock-onlysvgonpm update svgo --package-lock-onlyPosted once per head commit by the baseline gate (M2). A Renovate PR that only touches a manifest with no lockfile change is a broken pre-2026-08-06 artifact — check its diff before merging.
AI review · advisory
Verdict: 1 thing worth fixing (1 medium).
⚑ panel: GPT-OSS 120B · Gemma 4 31B · Devstral 2 123B · Laguna S 2.1 — 1 distinct, 1 confirmed, 0 below threshold, 0 refuted · web: not used · context: 2 files under review · 90 codebase · 14 standards chunks (best-grounded: GPT-OSS 120B; smaller windows saw less)
Panel debate — how this review was reached
Grounding — context: 2 files under review · 90 codebase · 14 standards chunks (best-grounded: GPT-OSS 120B; smaller windows saw less)
Round 1 — independent reviews
Round 2 — cross-examination
Devstral 2 123B#1Version mismatch in vitest dependency · confirmed: GPT-OSS 120B, Laguna S 2.1 · refuted: Gemma 4 31B · support 2Synthesis — Laguna S 2.1 wrote the final review from 1 confirmed finding · promotion: support ≥ 2, and no refutation at high severity.
Transcript
rv-20260909053347-b4c64a— full round outputs, web results, and model reasoning are viewable by anyone with access to this repository via the AI gateway.Advisory — never a merge gate. Findings are ordered by how well the panel's own evidence checks out, strongest first. React 👍/👎 on any inline comment to tell it whether it was worth flagging — that is the only feedback this system gets, and every threshold in it is tuned from those reactions. Transcript
rv-20260909053347-b4c64a.@ -23114,7 +23136,7 @@},package-lock.json:23136· MEDIUM — Version mismatch in vitest dependencyThe root package.json declares vitest ^4.1.10, but the workspace package packages/react/package.json declares ^4.1.11. This inconsistency can lead to different versions being installed across the monorepo, potentially causing compatibility issues.
Proposed replacement (one-click ⚡ Apply on the findings board at the top of this PR):
Evidence: partly verified — two or more reviewers, quote or anchor verified (panel 3/4).
👍 if this was worth flagging · 👎 if it was not — a reaction on this comment is the whole feedback loop.
0612d837a1a1967cb0bc🔧 Security-gate fix map
The gate failed on these dependency findings — fastest path to green for each:
@nuxtjs/mdc@tiptap/corenpm update core --package-lock-onlyjs-yamlnpm update js-yaml --package-lock-onlysharpnpm update sharp --package-lock-onlysvgonpm update svgo --package-lock-onlyPosted once per head commit by the baseline gate (M2). A Renovate PR that only touches a manifest with no lockfile change is a broken pre-2026-08-06 artifact — check its diff before merging.
AI review · advisory
Verdict: nothing confirmed — 2 single-reviewer observations in the debate digest below.
⚑ panel: Gemma 4 31B · Laguna S 2.1 (no review: GPT-OSS 120B, Devstral 2 123B) — 2 distinct, 0 confirmed, 2 below threshold, 0 refuted · web: not used · context: 2 files under review · 90 codebase · 6 standards chunks
Panel debate — how this review was reached
Grounding — context: 2 files under review · 90 codebase · 6 standards chunks
Round 1 — independent reviews
Round 2 — cross-examination
Laguna S 2.1#1Root package.json vitest range lags the lockfile bump · confirmed: Gemma 4 31B · refuted: — · support 1Laguna S 2.1#2packages/react lockfile devDependency pinned but root not advanced · confirmed: Gemma 4 31B · refuted: — · support 1Not posted (support < 2, or contested at a severity where one refutation vetoes)
Laguna S 2.1#1Root package.json vitest range lags the lockfile bump (support 1)Laguna S 2.1#2packages/react lockfile devDependency pinned but root not advanced (support 1)Synthesis — Laguna S 2.1 wrote the final review from 0 confirmed findings (+2 below threshold) · promotion: support ≥ 2, and no refutation at high severity.
Transcript
rv-20260928001438-c53ee0— full round outputs, web results, and model reasoning are viewable by anyone with access to this repository via the AI gateway.Advisory — never a merge gate. Findings are ordered by how well the panel's own evidence checks out, strongest first. React 👍/👎 on any inline comment to tell it whether it was worth flagging — that is the only feedback this system gets, and every threshold in it is tuned from those reactions. Transcript
rv-20260928001438-c53ee0.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.