CVE-2026-84373 vitest: Path traversal / arbitrary file read via @vitest/mocker redirect mocks (4.1.0 -> 4.1.11) - #1124
Open
dependabot[bot] wants to merge 1 commit into
Conversation
Bumps [@vitest/mocker](https://github.com/vitest-dev/vitest/tree/HEAD/packages/mocker) to 4.1.11 and updates ancestor dependency [vitest](https://github.com/vitest-dev/vitest/tree/HEAD/packages/vitest). These dependencies need to be updated together. Updates `@vitest/mocker` from 4.1.0 to 4.1.11 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/mocker) Updates `vitest` from 4.1.0 to 4.1.11 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v4.1.11/packages/vitest) --- updated-dependencies: - dependency-name: "@vitest/mocker" dependency-version: 4.1.11 dependency-type: indirect - dependency-name: vitest dependency-version: 4.1.11 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bumps
vitestinopenam-ui-js-sdkfrom 4.1.0 to 4.1.11, carrying the whole pinned@vitest/*set —expect,mocker,pretty-format,runner,snapshot,spy,utils— to the same version. The alert is on@vitest/mocker, which is an exact-version dependency ofvitest, so the two have to move together.AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N), EPSS 0.38%; affects@vitest/mockerandvitest>= 2.1.0, < 4.1.11, patched in 4.1.11 (and 5.0.0-rc.2). 2.1.x and 3.x are unmaintained and will not get the fix.Path traversal / arbitrary file read via redirect mocks
@vitest/mocker'sinterceptorPlugintakes a redirect mock's target path from client input and registers it without any boundary check:The plugin's
loadhook is the file-read sink —return readFile(mock.redirect, 'utf-8')— so whatever path was registered is handed back as module source the next time the mocked module is requested.join(root, new URL(redirect).pathname)is not a containment guard. For a special scheme (file:,http:) WHATWG URL collapses..during parsing, sofile:///../../etc/passwdstays under the root; for an opaque (non-special) scheme the..segments survive intopathname, andjoin(root, "../../…/etc/passwd")resolves outside the project root. And even without escaping the root, there is noserver.fs.allow/server.fs.denyconsultation at all, so an in-root file the dev server would otherwise refuse to serve — an.env, a denied source file — is readable too.Two registration channels reach that code, with different trust:
mockerPlugin/ standaloneinterceptorPlugin(the export third-party dev servers embed):configureServerhangsserver.ws.on('vitest:interceptor:register', …)on Vite's HMR WebSocket, which does no token, Origin, or same-origin check. This is the unauthenticated path the advisory scores.api.token, so the same missing check is only reachable with the token.4.1.11 validates the resolved target with Vite's
isFileLoadingAllowed(server.config, redirect)before registering and drops the registration if it fails, addscheckFileAccess()on the browser RPC path, and makes browser mode pass the newregisterWebSocketEvents: falseso the raw dev-server socket stops accepting mock registration at all.Scope in OpenAM
vitestis a dev-only dependency ofopenam-ui-js-sdk— every entry in the bumped subtree is"dev": true, the Maven build only runs it vianpm run test:run(vitest run, single pass, no watch and no API server), and theapp/libassemblies ziptarget/appandtarget/libonly. Nothing from this tree ships in the WAR.The vulnerable code is not reachable in this module as configured:
vitest.config.jsruns plain node tests (environment: 'jsdom'), not browser mode.@vitest/browser-playwright/-preview/-webdriverioare optional peers and none is installed;mswis not installed either.interceptorPluginup from exactly two places —@vitest/browser's server and the publicmockerPluginexport documented for third-party dev servers. The core node runner registers neither, sovitest runnever opens avitest:interceptor:registerhandler.npm run devdoes bind a dev server to every interface (vite --host 0.0.0.0), but that is plain Vite serving the demo app undervite.config.ts(plugins: [react()],server.allowedHosts: ["localhost", "openam.example.org"]) — no mocker plugin is loaded there.So the bump is hardening rather than an active-exploit fix: it takes the toolchain out of the affected range and keeps the door shut if the module later adopts browser mode or the public mocker plugin. No sibling module is left behind — neither
openam-ui-rianoropenam-ui-apiresolvesvitestat all. The module also sat exactly on 4.1.0 and was therefore already clear of GHSA-5xrq-8626-4rwp (>= 4.0.0, < 4.1.0); CVE-2026-84373 is the only vitest advisory that applied.Verified
package.jsonfloor moves^4.1.0->^4.1.11, so a freshnpm installcannot resolve back into the affected rangeintegrityhashes matchnpm view <pkg> dist.integrity:vitest@4.1.11,@vitest/expect@4.1.11,@vitest/mocker@4.1.11,@vitest/pretty-format@4.1.11,@vitest/runner@4.1.11,@vitest/snapshot@4.1.11,@vitest/spy@4.1.11,@vitest/utils@4.1.11,tinyrainbow@3.1.1vitepeer range tightens from^6.0.0 || ^7.0.0 || ^8.0.0-0to^6.0.0 || ^7.0.0 || ^8.0.0; the module resolvesvite@8.0.16, which satisfies both, so nothing else has to move@vitest/coverage-istanbuland@vitest/coverage-v8show up as new optional peers ofvitest; neither is installed and neither is requiredtinyrainbow3.1.0 -> 3.1.1 rides along on the raised^3.0.3->^3.1.0floor of the@vitest/*packages; it is the only non-@vitestpackage the lock file touchesimportOriginalwith the deps optimizer (#10546) and the restored global concurrency limit for test lifecycle hooks (#10992)Upstream: advisory · #10974 / fe5a11d (v4 backport) · #10972 (main) · 4.1.11 release