CVE-2026-93604 Overview
CVE-2026-93604 is an access control weakness [CWE-284] in the vm2 sandbox library through version 3.12.0. When an embedder allowlists the crypto builtin for a NodeVM using require.builtin: ['crypto'], guest code can invoke crypto.setFips() and toggle the FIPS mode of the entire host Node.js process. The sanitizeCryptoModule function in lib/builtin.js strips crypto.setEngine but does not remove or wrap crypto.setFips. The readonly proxy exposing the host module fails to localize side effects of forwarded host functions, allowing guest state changes to persist in the host. The issue is fixed in vm2 3.12.1.
Critical Impact
Untrusted guest code inside a NodeVM can mutate host process cryptographic state, crossing the sandbox isolation boundary and affecting trusted host code that later reads crypto.getFips().
Affected Products
- vm2 versions up to and including 3.12.0
- Node.js applications embedding vm2 with require.builtin: ['crypto']
- Downstream libraries and services relying on vm2 for sandboxed guest execution
Discovery Timeline
- 2026-09-18 - CVE-2026-93604 published to the National Vulnerability Database (NVD)
- 2026-09-18 - Last updated in NVD database
Technical Details for CVE-2026-93604
Vulnerability Analysis
vm2 is a Node.js library designed to run untrusted code within an isolated sandbox. The NodeVM construct lets embedders selectively allow guest access to built-in modules through the require.builtin allowlist. When crypto is included in that allowlist, vm2 hands the guest a wrapped view of the host crypto module, sanitized by sanitizeCryptoModule in lib/builtin.js.
The sanitizer removes crypto.setEngine, which is a known host-mutating function, but leaves crypto.setFips reachable through the readonly wrapper. That wrapper forwards calls to the host implementation without isolating side effects. As a result, a guest call to crypto.setFips(1) reconfigures FIPS mode for the entire Node.js process, and trusted host code subsequently observes the change via crypto.getFips() returning 1 instead of 0.
The root defect is an incomplete allowlist and an insufficient wrapper contract, which together break the isolation guarantee that the NodeVM boundary is meant to provide.
Root Cause
The vulnerability stems from two design gaps. First, sanitizeCryptoModule enumerates only a subset of host-mutating APIs and misses crypto.setFips. Second, the readonly proxy used to expose host modules to guest code does not intercept or sandbox the side effects of forwarded function calls. Host process state therefore becomes writable through any unfiltered function that the wrapper exposes.
Attack Vector
An attacker who can supply JavaScript to a NodeVM configured with the crypto builtin allowlist requires crypto and calls setFips(1). No authentication or user interaction is required beyond the ability to submit guest code. The FIPS mode change persists across the process, affecting cryptographic operations performed by any host or peer guest code that reads or depends on FIPS state.
A proof of concept is described in the VulnCheck Advisory on vm2 and the GitHub Security Advisory. The exploit consists of a short guest script that imports crypto and invokes setFips, after which the host observes the modified mode.
Detection Methods for CVE-2026-93604
Indicators of Compromise
- Unexpected transitions of crypto.getFips() from 0 to 1 (or vice versa) in host process telemetry
- Guest scripts containing require('crypto').setFips( or crypto.setFips( submitted to sandboxed evaluation endpoints
- Cryptographic operations in the host process failing or behaving inconsistently after guest code execution
Detection Strategies
- Inventory Node.js services that depend on vm2 and identify those configuring NodeVM with require.builtin including crypto
- Perform static analysis of guest code submissions for references to setFips, setEngine, or other host-mutating crypto APIs
- Instrument the host runtime to log calls to crypto.setFips and correlate with sandbox execution events
Monitoring Recommendations
- Emit an audit event whenever crypto.getFips() changes value during process lifetime
- Track vm2 package versions across build artifacts and container images using software composition analysis
- Alert on any NodeVM construction that includes crypto in require.builtin on the version range 0 through 3.12.0
How to Mitigate CVE-2026-93604
Immediate Actions Required
- Upgrade vm2 to version 3.12.1 or later in all applications and container images
- Audit NodeVM configurations and remove crypto from require.builtin unless strictly required
- Review guest code submission logs for prior invocations of crypto.setFips and validate cryptographic integrity of downstream operations
Patch Information
The maintainers fixed the issue in vm2 3.12.1 by extending sanitizeCryptoModule to also block crypto.setFips. Consult the GitHub Security Advisory GHSA-x3v6-43hc-82mc for the patch commit and release notes. Note that vm2 has been deprecated by its maintainer in favor of alternative isolation approaches; teams should also evaluate migrating to process-level or V8 isolated-vm based sandboxing.
Workarounds
- Remove crypto from the require.builtin allowlist passed to NodeVM if upgrading is not immediately feasible
- Wrap the exposed crypto object with a custom proxy that deletes or throws on setFips and other host-mutating methods
- Enforce a defense-in-depth boundary by executing untrusted guest code in a separate OS process with FIPS mode fixed at startup
# Upgrade vm2 to the patched release
npm install vm2@3.12.1
# Verify the installed version
npm ls vm2
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

