CVE-2026-47210
JavaScript 취약성 분석 및 완화

개요

CVE-2026-47210 is a critical sandbox escape vulnerability in the vm2 Node.js sandboxing library, titled "vm2 sandbox escape via JSPI-backed Promise .finally() species bypass." It affects all versions of vm2 up to and including 3.11.3 (npm package), and was discovered and published on May 18, 2026, with the GitHub Advisory Database entry published May 29, 2026. The vulnerability allows arbitrary code execution in the host process when untrusted code is executed with async support on Node.js runtimes exposing WebAssembly JSPI (WebAssembly.promising / WebAssembly.Suspending), which is enabled by default in Node.js 26+. It carries a CVSS v3.1 base score of 9.8 (Critical) (GitHub Advisory, vm2 Security Advisory).

기술적 세부 사항

The root cause is classified as CWE-913 (Improper Control of Dynamically-Managed Code Resources). On Node.js 26+, WebAssembly.promising(...) returns Promise objects whose [[Prototype]] chain points directly at the host realm's Promise.prototype with no bridge proxy interposed — bypassing vm2's sandbox-side globalPromise.prototype overrides, resetPromiseSpecies hardening, and the bridge apply-trap callback wrapping. An attacker can install a getter on p.constructor pointing to an attacker-controlled class F with a custom [Symbol.species], then call p.finally(()=>{}). This causes V8's host-realm SpeciesConstructor to read F and invoke NewPromiseCapability(F), storing sandbox closures as raw [[Resolve]]/[[Reject]] with no bridge mediation. When a host-realm TypeError is dispatched through F's reject closure, e.constructor.constructor('return process')() evaluates in the host realm, achieving full RCE. A working PoC was included in the advisory and targets the node:26-bookworm environment (GitHub Advisory, Patch Commit).

영향

Successful exploitation results in complete compromise of the host process running vm2, with full confidentiality, integrity, and availability impact. An unauthenticated attacker can execute arbitrary OS commands, read or write any files accessible to the host process, and steal secrets, tokens, credentials, and application data. Any service relying on vm2 as a security boundary — such as code execution platforms, plugin sandboxes, or multi-tenant JavaScript evaluation environments — is fully compromised, with potential for lateral movement within the host infrastructure (GitHub Advisory, vm2 Security Advisory).

착취 단계

  1. Identify target: Locate applications that accept and execute attacker-controlled JavaScript using vm2 as a sandbox boundary, particularly those running on Node.js 26+ (where WebAssembly JSPI is enabled by default) or Node.js 24 with --experimental-wasm-jspi.
  2. Craft malicious WebAssembly module: Prepare a minimal WASM binary that imports a JS function wrapped with WebAssembly.Suspending, causing a host-realm TypeError during JSPI processing (e.g., by passing an invalid argument to WebAssembly.compileStreaming).
  3. Instantiate WASM and obtain JSPI Promise: Inside the vm2 sandbox, call WebAssembly.instantiate(wasmBytes, imports).then(r => { let p = WebAssembly.promising(r.instance.exports.run)(); ... }) to obtain a JSPI-backed Promise p whose [[Prototype]] is the host realm's Promise.prototype.
  4. Install attacker-controlled species: Define a class F with a constructor that captures the reject callback. In the reject handler, use e.constructor.constructor('return process')() to escape to the host realm. Set F[Symbol.species] to F and override p.constructor with a getter returning F.
  5. Trigger the bypass via .finally(): Call p.finally(()=>{}). V8's host-realm SpeciesConstructor reads F from p.constructor, invokes NewPromiseCapability(F), and when the host-realm TypeError is dispatched, F's reject closure executes in the host realm.
  6. Execute arbitrary commands: Within the reject closure, call e.constructor.constructor('return process')().mainModule.require('child_process').execSync('<command>') to run arbitrary OS commands as the host process user (GitHub Advisory, Patch Commit).

타협의 징후

  • Process: Unexpected child processes spawned by the Node.js process running vm2 (e.g., sh, bash, execSync calls to touch, curl, wget, or reverse shell commands); unusual child_process module usage originating from vm2 sandbox execution context.
  • File System: Unexpected files created or modified by the Node.js process (e.g., a file named pwned as demonstrated in the PoC); new scripts, cron jobs, or SSH keys written by the host process.
  • Logs: Application logs showing vm2 execution of code containing WebAssembly.promising, WebAssembly.Suspending, Symbol.species, or constructor.constructor patterns; Node.js unhandled rejection or TypeError stack traces related to JSPI processing.
  • Network: Unexpected outbound connections from the Node.js host process to external IPs (indicative of reverse shell or data exfiltration following exploitation) (GitHub Advisory).

완화 및 해결 방법

Upgrade vm2 to version 3.11.4 or later, which removes WebAssembly.promising and WebAssembly.Suspending from the sandbox at bootstrap, eliminating the JSPI attack surface entirely (vm2 Release, Patch Commit). As a temporary workaround prior to patching, disable async support and WebAssembly JSPI within vm2 configurations, or avoid running vm2 on Node.js 26+ (where JSPI is default-on) and Node.js 24 with --experimental-wasm-jspi. Organizations should also consider whether vm2 is an appropriate security boundary for their threat model, given its history of sandbox escapes (GitHub Advisory).

커뮤니티 반응

The vulnerability received coverage from security news outlets including Heise and SecurityOnline, which reported on the batch of critical vm2 sandbox escapes closed in the v3.11.4 release. BeyondMachines also covered the broader set of critical sandbox escapes enabling remote code execution in vm2. The disclosure was noted as part of a pattern of recurring sandbox escapes in vm2, reinforcing community concerns about using vm2 as a reliable security boundary in production environments (Heise, SecurityOnline, BeyondMachines).

추가 자료


근원이 보고서는 AI를 사용하여 생성되었습니다.

관련 JavaScript 취약점:

CVE ID

심각도

점수

기술

구성 요소 이름

CISA KEV 익스플로잇

수정 사항이 있습니다.

게시된 날짜

CVE-2026-54157CRITICAL9
  • JavaScriptJavaScript
  • @lobehub/lobehub
아니요Jun 16, 2026
CVE-2026-42089HIGH8.6
  • JavaScriptJavaScript
  • yeoman-environment
아니요Jun 16, 2026
CVE-2026-47684HIGH7.7
  • JavaScriptJavaScript
  • @sync-in/server
아니요Jun 16, 2026
CVE-2026-54298MEDIUM4.2
  • JavaScriptJavaScript
  • astro
아니요Jun 16, 2026
CVE-2026-54326LOW2.5
  • JavaScriptJavaScript
  • @earendil-works/pi-coding-agent
아니요Jun 16, 2026

무료 취약성 평가

클라우드 보안 태세를 벤치마킹합니다

9개의 보안 도메인에서 클라우드 보안 관행을 평가하여 위험 수준을 벤치마킹하고 방어의 허점을 식별합니다.

평가 요청

추가 Wiz 리소스

맞춤형 데모 받기

맞춤형 데모 신청하기

"내가 본 최고의 사용자 경험은 클라우드 워크로드에 대한 완전한 가시성을 제공합니다."
데이비드 에슬릭최고정보책임자(CISO)
"Wiz는 클라우드 환경에서 무슨 일이 일어나고 있는지 볼 수 있는 단일 창을 제공합니다."
아담 플레처최고 보안 책임자(CSO)
"우리는 Wiz가 무언가를 중요한 것으로 식별하면 실제로 중요하다는 것을 알고 있습니다."
그렉 포니아토프스키위협 및 취약성 관리 책임자