Skip to content

fix(deps): upgrade vitest to ^4.1.0 to patch critical Vitest UI advisory (GHSA-5xrq-8626-4rwp)#4837

Merged
waleedlatif1 merged 4 commits into
stagingfrom
waleedlatif1/miami-v3
Jun 1, 2026
Merged

fix(deps): upgrade vitest to ^4.1.0 to patch critical Vitest UI advisory (GHSA-5xrq-8626-4rwp)#4837
waleedlatif1 merged 4 commits into
stagingfrom
waleedlatif1/miami-v3

Conversation

@waleedlatif1
Copy link
Copy Markdown
Collaborator

Summary

  • Bump vitest and @vitest/coverage-v8 to ^4.1.0 across all workspaces to resolve the critical Dependabot alert GHSA-5xrq-8626-4rwp ("When Vitest UI server is listening, arbitrary file can be read and executed"). 4.1.0 is the only patched release — there is no 3.x backport.
  • Migrate constructor mocks to class expressions. Vitest 4 invokes mocks called with new via Reflect.construct, and arrow/function implementations aren't constructable (function expressions also get reverted to arrows by biome's useArrowFunction, so classes are the stable fix).
  • Remove deprecated test.poolOptions from apps/sim/vitest.config.ts (options are now top-level in vitest 4).
  • Widen @sim/testing peer range to ^3.0.0 || ^4.0.0.

Type of Change

  • Bug fix (security)

Testing

  • Full apps/sim suite green under vitest 4.1.7: 7452 passed (484 files)
  • All other workspace suites pass (utils, logger, security, audit, ts-sdk, db, realtime)
  • bunx biome check clean on all changed files (no useArrowFunction/noConstructorReturn diagnostics)
  • bun run check:api-validation passes

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…ory (GHSA-5xrq-8626-4rwp)

- Bump vitest and @vitest/coverage-v8 to ^4.1.0 across all workspaces (only patched release for the critical 'Vitest UI server arbitrary file read/execute' advisory; no 3.x backport exists)
- Widen @sim/testing peer range to ^3.0.0 || ^4.0.0
- Migrate constructor mocks to class expressions: vitest 4 uses Reflect.construct for mocks invoked with new, and arrow/function implementations are not constructable (function expressions also get reverted to arrows by biome's useArrowFunction)
- Remove deprecated test.poolOptions from apps/sim/vitest.config.ts (options are now top-level in vitest 4)
@vercel
Copy link
Copy Markdown

vercel Bot commented Jun 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 1, 2026 10:45pm

Request Review

@cursor
Copy link
Copy Markdown

cursor Bot commented Jun 1, 2026

PR Summary

Low Risk
Dependency and test-infrastructure changes only; production runtime code is largely untouched aside from the security patch in dev tooling.

Overview
Upgrades Vitest and @vitest/coverage-v8 to ^4.1.0 across the monorepo (including bun.lock) to address GHSA-5xrq-8626-4rwp; there is no patched 3.x release.

Vitest 4 builds constructor mocks via Reflect.construct, so many tests and @sim/testing helpers now use class-based mockImplementation (sometimes with constructor return overrides for Date, S3Client, Executor, etc.). apps/sim/vitest.config.ts drops nested poolOptions in favor of top-level isolate: true. @sim/testing widens the Vitest peer range and adjusts small mocks (e.g. db transaction typing, LoggingSession / OAuth provider builders).

isolated-vm.test.ts replaces flaky sleep-based queue tests with createControllableReadyProc so concurrency limits are asserted deterministically.

Reviewed by Cursor Bugbot for commit e8dc247. Configure here.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Jun 1, 2026

Greptile Summary

This PR patches the critical Vitest UI arbitrary-file-read/execute vulnerability (GHSA-5xrq-8626-4rwp) by upgrading vitest and @vitest/coverage-v8 from ^3.0.8 to ^4.1.0 across all workspaces, and performs the accompanying Vitest 4 migration work.

  • Security bump: All workspace package.json files updated to ^4.1.0; packages/testing peer range tightened to ^3.0.0 || >=4.1.0 <5.0.0 to exclude the unpatched 4.0.x builds.
  • Mock migration: Constructor mocks previously using arrow/function return expressions (which Vitest 4 rejects via Reflect.construct) are migrated to class expressions with Object.assign(this, …) or class field initializers throughout all test files.
  • Config migration: poolOptions.threads block removed from apps/sim/vitest.config.ts and isolate: true promoted to top-level; useAtomics and singleThread are removed upstream in Vitest 4 with no replacement needed.

Confidence Score: 5/5

Safe to merge; correctly patches the critical file-read/execute advisory across all workspaces with no functional regressions.

The change is a well-scoped dependency upgrade with thorough mock migration. The Vitest 4 migration guide confirms that useAtomics and singleThread were removed upstream (not renamed), so dropping them without replacement is correct. The peer range in packages/testing has already been tightened to exclude the unpatched 4.0.x builds. All 7452 tests passed under the new version. The only observation is a minor type widening in a test-only mock file.

No files require special attention.

Important Files Changed

Filename Overview
apps/sim/vitest.config.ts Removes deprecated poolOptions.threads block; isolate: true correctly promoted to top-level; useAtomics and singleThread: false deliberately dropped as they were removed in Vitest 4.
packages/testing/package.json Peer range correctly set to `^3.0.0
packages/testing/src/mocks/database.mock.ts Transaction callback parameter type loosened from typeof dbChainMock.db to any; adds Promise<unknown> return type annotation. Minor type safety regression in shared test infrastructure.
packages/testing/src/mocks/logging-session.mock.ts Extracts buildLoggingSessionInstance as a named function (constructable, not an arrow) so Vitest 4's Reflect.construct path works; returned plain object correctly overrides the constructed this.
packages/testing/src/mocks/mcp-oauth.mock.ts Extracts buildSimMcpOauthProvider as a named function to make the mock constructable; identity-passthrough semantics preserved via constructor return.
apps/sim/lib/mcp/connection-manager.test.ts All constructor mocks migrated to class expressions with Object.assign(this, instance); spy references remain intact so all assertions are unaffected.
apps/sim/lib/execution/isolated-vm.test.ts Queue-full and per-owner-limit tests replaced sleep-based timing with a deterministic createControllableReadyProc helper; removes flakiness and the sleep import. Logic is sound.
apps/sim/lib/core/config/redis.test.ts Redis constructor mock migrated to class expression with Object.assign(this, mockRedisInstance); retryStrategy test also updated consistently.
apps/sim/lib/uploads/providers/s3/client.test.ts S3 mock constructor returns mockS3Client identity via constructor override (needed to preserve shared spy references); command mocks changed to empty classes.
apps/sim/lib/workflows/executor/execution-core.test.ts Executor and Serializer mocks migrated; Executor still uses constructor-return override (identity required), Serializer uses clean class fields.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["vi.fn().mockImplementation(impl)"] --> B{Called with `new`?}
    B -->|"Vitest 3 (arrow/fn return)"| C["Return value used directly\n✅ worked"]
    B -->|"Vitest 4 (arrow fn)"| D["Reflect.construct(arrowFn, …)\n❌ TypeError: Not a constructor"]
    B -->|"Vitest 4 (class expression)"| E["Reflect.construct(class, …)\n✅ constructable"]
    E --> F{Constructor returns object?}
    F -->|"return non-primitive"| G["Returned obj overrides `this`\n(used for identity passthrough)"]
    F -->|"Object.assign(this, …)"| H["Methods copied onto `this`\n(spy refs preserved)"]
    F -->|"Class field initializers"| I["Properties set directly on instance\n(cleanest pattern)"]
    G --> J["✅ Tests pass under Vitest 4"]
    H --> J
    I --> J
Loading

Reviews (3): Last reviewed commit: "test(isolated-vm): de-flake queue-capaci..." | Re-trigger Greptile

Comment thread packages/testing/package.json Outdated
Tighten the v4 arm of the peer range to >=4.1.0 <5.0.0 so the peer
requirement cannot be satisfied by the unpatched 4.0.x builds that
GHSA-5xrq-8626-4rwp affects.
- logging-session & mcp-oauth mocks: a class passed to mockImplementation has
  a construct signature that isn't assignable to its (...args) => any parameter,
  failing tsc. Use named function declarations instead (constructable via
  Reflect.construct, assignable to mockImplementation, and not rewritten to
  arrows by biome's useArrowFunction).
- database.mock.ts: vitest 4's generic vi.fn typings no longer break the
  self-referential cycle on the transaction callback's tx param; loosen tx and
  annotate the callback's return type to resolve the implicit-any errors.
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 8b6fc53. Configure here.

The 'queue is full' and 'per-owner queued limit' tests relied on
'await sleep(1)' to assume the first request had reached the queue before
submitting the overflow request. The first request only enqueues after an
async spawn-failure chain (acquireWorker -> spawn exit -> resolve null ->
enqueue), which isn't guaranteed within 1ms under CI load — the overflow
request then found an empty queue and hit the 200ms queue-wait timeout
instead of the capacity rejection.

Replace the wall-clock barrier with a deterministic, event-driven one: hold
the single global concurrency slot (IVM_MAX_CONCURRENT=1) with an active
worker and await an explicit 'dispatched' signal (fired when the worker
receives its execute message, after the scheduler counts it active). The
follow-up requests then deterministically hit the synchronous enqueue path.
Also drops the queue-wait timeout from 200ms to 50ms, so the tests run faster.
@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1
Copy link
Copy Markdown
Collaborator Author

@cursor review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit e8dc247. Configure here.

@waleedlatif1 waleedlatif1 merged commit a7b0bd3 into staging Jun 1, 2026
14 checks passed
@waleedlatif1 waleedlatif1 deleted the waleedlatif1/miami-v3 branch June 1, 2026 23:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant