Skip to main content

vm2 EUVDEUVD-2026-60461

| CVE-2026-47683 HIGH
Allocation of Resources Without Limits or Throttling (CWE-770)
2026-08-17 https://github.com/patriksimek/vm2 GHSA-gmc2-2x9w-cgh9
8.7
CVSS 4.0 · Vendor: https://github.com/patriksimek/vm2
Share

Severity by source

Vendor (https://github.com/patriksimek/vm2) PRIMARY
8.7 HIGH
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
vuln.today AI
7.5 HIGH

Network vector with no privilege requirement, as applications exposing vm2 sandboxes typically accept untrusted code without authentication; impact is availability-only with unchanged scope since no sandbox escape occurs.

3.1 AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
4.0 AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Primary rating from Vendor (https://github.com/patriksimek/vm2).

CVSS VectorVendor: https://github.com/patriksimek/vm2

CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X
Attack Vector
Network
Attack Complexity
Low
Privileges Required
None
User Interaction
None
Scope
X

Lifecycle Timeline

7
Patch available
Aug 17, 2026 - 22:03 EUVD
Analysis Updated
Aug 17, 2026 - 21:29 vuln.today
v2 (cvss_changed)
Re-analysis Queued
Aug 17, 2026 - 21:22 vuln.today
cvss_changed
CVSS changed
Aug 17, 2026 - 21:22 NVD
8.7 (HIGH)
Source Code Evidence Fetched
Aug 17, 2026 - 18:36 vuln.today
Analysis Generated
Aug 17, 2026 - 18:36 vuln.today
CVE Published
Aug 17, 2026 - 17:32 cve.org
HIGH

Blast Radius

ecosystem impact
† from your stack dependencies † transitive graph · vuln.today resolves 4-path depth
  • 4,224 npm packages depend on vm2 (1,156 direct, 3,100 indirect)

Ecosystem-wide dependent count for version 3.11.6.

DescriptionCVE.org

Summary

vm2 bufferAllocLimit cap bypassed by Buffer.concat and Buffer.from arrayLike

The bufferAllocLimit option introduced in 3.11.0 (GHSA-6785-pvv7-mvg7) caps host-side Buffer allocations driven by sandbox code, the way embedders opt into timeout. The cap wraps Buffer.alloc, Buffer.allocUnsafe, Buffer.allocUnsafeSlow, and the deprecated Buffer(N) / new Buffer(N) forms. Two other API paths reach the same host C++ allocator with an attacker-controlled size and are not capped: Buffer.concat(list, totalLength) and Buffer.from(arrayLike) with a fake length. Sandbox code can use either to allocate an arbitrary number of host external bytes in a single call, defeating the explicit DoS mitigation the embedder configured.

Details

lib/setup-sandbox.js installs checkBufferAllocLimit at every wrapped entry to host Buffer allocation:

  • alloc() at lib/setup-sandbox.js:474 and the connect(alloc, host.Buffer.alloc) at line 480.
  • allocUnsafe() at line 488 and connect(allocUnsafe, host.Buffer.allocUnsafe) at line 496.
  • allocUnsafeSlow() at line 504 and connect(allocUnsafeSlow, host.Buffer.allocUnsafeSlow) at line 510.
  • BufferHandler.apply at line 424 and BufferHandler.construct at line 433 for the deprecated Buffer(N) / new Buffer(N) numeric-first-arg paths.

Buffer.concat is not wrapped. The sandbox-visible Buffer.concat is therefore the bridge proxy of the host Buffer.concat, which calls into Node's Buffer.allocUnsafe(totalLength) internally without going through the sandbox-side allocUnsafe wrapper. Same for Buffer.from when the argument is array-like ({length: N}): Node's fromArrayLike allocates a buffer of size N before the iteration that fills it. Neither of those allocator paths consult localBufferAllocLimit.

The mitigation rationale documented in docs/ATTACKS.md Category 23 explicitly enumerates the surfaces that were considered and either capped (Buffer.alloc family) or punted to follow-up (new Uint8Array(N), new ArrayBuffer(N), String.prototype.repeat). Buffer.concat(list, totalLength) is not listed in either group, and Buffer.from(arrayLike) is mentioned only as "bounded by source array size which had to be allocated through some other path first" -- which is not true for the {length: N} form, because no array of length N actually exists.

A single call from sandbox to Buffer.concat([Buffer.from('a')], 50 * 1024 * 1024) allocates 50 MiB of host external memory. The allocation itself is a single synchronous host C++ call that timeout cannot interrupt, exactly like the original advisory. The zero-fill that follows is interruptible, but the memory is already committed by the time the interrupt could fire, so the embedder's container memory budget is the only ceiling. The same pattern in a loop, or with a larger totalLength, drives RSS up by hundreds of megabytes per call.

The fix uses the existing checkBufferAllocLimit(size) helper and a sandbox-side wrapper installed via connect(...) -- one for Buffer.concat that sums the totalLength (or falls back to summing list lengths) and one for Buffer.from that recognises the array-like-with-numeric-length branch.

PoC

javascript
'use strict';
const { VM, NodeVM } = require('vm2');

function ext() { return Math.round(process.memoryUsage().external / 1024 / 1024); }
function tryBypass(label, code) {
    const ext0 = ext();
    let buf;
    try { buf = code(); }
    catch (e) {
        console.log(`[${label}] CAPPED -- ${String(e).split('\n')[0]}`);
        return;
    }
    console.log(`[${label}] BYPASSED -- got ${buf && buf.length} bytes (external +${ext() - ext0} MB)`);
}

console.log('Cap is configured at 1024 bytes.\n');

const vm1 = new VM({ bufferAllocLimit: 1024 });
tryBypass('VM Buffer.alloc(50MB)        ',
    () => vm1.run('Buffer.alloc(50 * 1024 * 1024)'));

const vm2 = new VM({ bufferAllocLimit: 1024 });
tryBypass('VM Buffer.concat 50MB        ',
    () => vm2.run('Buffer.concat([Buffer.from("a")], 50 * 1024 * 1024)'));

const vm3 = new NodeVM({ bufferAllocLimit: 1024 });
tryBypass('NodeVM Buffer.concat 50MB    ',
    () => vm3.run('module.exports = Buffer.concat([Buffer.from("a")], 50 * 1024 * 1024);'));

const vm4 = new VM({ bufferAllocLimit: 1024 });
tryBypass('VM Buffer.from({length: 8MB})',
    () => vm4.run('Buffer.from({length: 8 * 1024 * 1024})'));

Run with node poc.js against vm2@3.11.3:

Cap is configured at 1024 bytes.

[VM Buffer.alloc(50MB)        ] CAPPED -- RangeError: Buffer allocation size 52428800 exceeds bufferAllocLimit 1024
[VM Buffer.concat 50MB        ] BYPASSED -- got 52428800 bytes (external +50 MB)
[NodeVM Buffer.concat 50MB    ] BYPASSED -- got 52428800 bytes (external +50 MB)
[VM Buffer.from({length: 8MB})] BYPASSED -- got 8388608 bytes (external +8 MB)

Process RSS climbs by the same amount each call, confirming a real host C++ allocation rather than a sandbox-realm-only effect.

Impact

This is the same DoS class GHSA-6785-pvv7-mvg7 was filed for: untrusted sandbox code amplifying a small payload into a large synchronous host external-memory allocation that V8's timeout cannot preempt. In the environments the advisory cites -- Docker memory limits, Kubernetes pods, AWS Lambda -- a single 200-byte sandbox payload can drive a multi-hundred-megabyte RSS jump and OOM the host process.

The Category 23 fix was specifically scoped to "cap host Buffer external allocation" and embedders are documented to opt into bufferAllocLimit as their layered defense against this class. The two paths above are uncapped, so an embedder that has configured bufferAllocLimit: 32 * 1024 * 1024 (the value recommended in the README's Hardening recommendations) is still vulnerable to the exact attack the option was designed to prevent. The mitigation invariant -- "every Buffer external allocation driven by sandbox code is capped by bufferAllocLimit" -- does not hold.

No sandbox escape; pure DoS.

AnalysisAI

Denial-of-service in vm2 (Node.js sandbox library) versions 3.11.0-3.11.5 allows sandbox code to bypass the bufferAllocLimit DoS mitigation via two unwrapped allocation paths - Buffer.concat(list, totalLength) and Buffer.from({length: N}) - committing unbounded host external memory in a single synchronous C++ call that V8's timeout mechanism cannot interrupt. A publicly available PoC confirms that a 200-byte sandbox payload inflates host RSS by hundreds of megabytes per invocation, making a single crafted request sufficient to OOM-kill a host process running inside a Docker container, Kubernetes pod, or AWS Lambda function. …

Unlock full vulnerability intelligence

  • Risk assessment & exploitation conditions
  • Attack chain visualization
  • Remediation with exact patch versions
  • Threat intelligence from 22 sources
  • Personal watchlist & email alerts

Free forever · No credit card required

Attack ChainAIDerived

Hypothetical attack flow derived from CVE metadata

Access
Submit crafted JS payload to vm2 sandbox endpoint
Delivery
Invoke Buffer.concat with attacker-controlled totalLength
Exploit
Bypass bufferAllocLimit via unwrapped host allocator path
Execution
Synchronously commit host external memory before timeout fires
Persist
Repeat calls or scale totalLength to exhaust container memory limit
Impact
Host process terminated by OOM killer

Vulnerability AssessmentAI

Exploitation Exploitation requires three concrete conditions: (1) the target application runs vm2 version 3.11.0-3.11.5 with the `bufferAllocLimit` option set - applications without `bufferAllocLimit` are already subject to the parent advisory GHSA-6785-pvv7-mvg7; (2) the attacker can execute arbitrary JavaScript code inside the vm2 sandbox, typically via an API endpoint or service that accepts user-provided code strings; and (3) the host process is subject to a finite memory budget (container limit, Lambda memory cap) that can be exhausted. … Additional conditions and limiting factors are described in the full assessment.
Risk Assessment The CVSS 4.0 score of 8.7 (AV:N/AC:L/AT:N/PR:N/UI:N/VA:H) accurately reflects high availability impact with no complexity or privilege barrier. … Full risk analysis with EPSS, KEV, and SSVC signal comparison available after sign-in.
Exploit Scenario An attacker submits a 200-byte JavaScript payload to an application endpoint that evaluates user-supplied code in a vm2 sandbox: `Buffer.concat([Buffer.from('a')], 500 * 1024 * 1024)`. The call bypasses the configured `bufferAllocLimit` and commits 500 MiB of host external memory synchronously - before V8's timeout interrupt fires - causing the container's memory limit to be breached and the host process to be OOM-killed. …
Remediation Upgrade to vm2 3.11.6 immediately; this release installs sandbox-side wrappers via `connect(...)` for `Buffer.concat`, `Buffer.from`, and `Buffer.copyBytesFrom` that consult `localBufferAllocLimit` before delegating to the host allocator, restoring the intended invariant. … Detailed patch versions, workarounds, and compensating controls in full report.

Recommended ActionAI

Within 24 hours, enumerate all systems running vm2 versions 3.11.0-3.11.5 and assess their exposure (determine whether they execute untrusted/user-supplied code). …

Sign in for detailed remediation steps and compensating controls.

Threat intelligence, references, and detailed analysis are available after sign-in.

CVE-2025-1974 CRITICAL POC
9.8 Mar 25

A critical vulnerability in Kubernetes ingress-nginx controller allows unauthenticated attackers with pod network access

CVE-2026-45321 CRITICAL POC
9.6 May 12

Credential-harvesting malware compromised 84 versions of 42 TanStack npm packages on 2026-05-11 via chained GitHub Actio

CVE-2025-1098 HIGH POC
8.8 Mar 25

Kubernetes ingress-nginx contains a configuration injection vulnerability via the mirror-target and mirror-host Ingress

CVE-2025-24514 HIGH POC
8.8 Mar 25

A security issue was discovered in ingress-nginx https://github.com/kubernetes/ingress-nginx where the `auth-url` Ingres

CVE-2025-1097 HIGH POC
8.8 Mar 25

A security issue was discovered in ingress-nginx https://github.com/kubernetes/ingress-nginx where the `auth-tls-match-c

CVE-2020-8554 MEDIUM POC
6.3 Jan 21

Kubernetes API server in all versions allow an attacker who is able to create a ClusterIP service and set the spec.exter

CVE-2023-3676 HIGH POC
8.8 Oct 31

A security issue was discovered in Kubernetes where a user that can create pods on Windows nodes may be able to escalate

CVE-2025-55190 CRITICAL POC
9.9 Sep 04

Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Rated critical severity (CVSS 9.9), this vulne

CVE-2026-34976 CRITICAL POC
10.0 Apr 02

Unauthenticated remote attackers can trigger complete database overwrites, server-side file reads, and SSRF attacks agai

CVE-2018-18843 CRITICAL POC
10.0 Dec 04

The Kubernetes integration in GitLab Enterprise Edition 11.x before 11.2.8, 11.3.x before 11.3.9, and 11.4.x before 11.4

CVE-2026-54680 CRITICAL POC
9.9 Jul 29

Fluentd configuration injection in the kube-logging Logging operator before 6.6.0 allows a namespace-scoped user who can

CVE-2026-22039 CRITICAL POC
9.9 Jan 27

Kyverno Kubernetes policy engine prior to 1.x has a privilege escalation vulnerability (CVSS 9.9) allowing policy bypass

Share

EUVD-2026-60461 vulnerability details – vuln.today

This site uses cookies essential for authentication and security. No tracking or analytics cookies are used. Privacy Policy