{"url":"https://api.github.com/repos/patriksimek/vm2/releases/324282449","assets_url":"https://api.github.com/repos/patriksimek/vm2/releases/324282449/assets","upload_url":"https://uploads.github.com/repos/patriksimek/vm2/releases/324282449/assets{?name,label}","html_url":"https://github.com/patriksimek/vm2/releases/tag/v3.11.4","id":324282449,"author":{"login":"patriksimek","id":1000058,"node_id":"MDQ6VXNlcjEwMDAwNTg=","avatar_url":"https://avatars.githubusercontent.com/u/1000058?v=4","gravatar_id":"","url":"https://api.github.com/users/patriksimek","html_url":"https://github.com/patriksimek","followers_url":"https://api.github.com/users/patriksimek/followers","following_url":"https://api.github.com/users/patriksimek/following{/other_user}","gists_url":"https://api.github.com/users/patriksimek/gists{/gist_id}","starred_url":"https://api.github.com/users/patriksimek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/patriksimek/subscriptions","organizations_url":"https://api.github.com/users/patriksimek/orgs","repos_url":"https://api.github.com/users/patriksimek/repos","events_url":"https://api.github.com/users/patriksimek/events{/privacy}","received_events_url":"https://api.github.com/users/patriksimek/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"RE_kwDOAPKd984TVChR","tag_name":"v3.11.4","target_commitish":"main","name":"v3.11.4","draft":false,"immutable":false,"prerelease":false,"created_at":"2026-05-18T12:40:09Z","updated_at":"2026-05-18T12:42:49Z","published_at":"2026-05-18T12:42:49Z","assets":[],"tarball_url":"https://api.github.com/repos/patriksimek/vm2/tarball/v3.11.4","zipball_url":"https://api.github.com/repos/patriksimek/vm2/zipball/v3.11.4","body":"Ten advisories closed. Patch release — no API changes for valid configurations.\r\n\r\n## What's Changed\r\n\r\n### Security fixes\r\n\r\n- **GHSA-c4cf-2hgv-2qv6** — Bridge `set` trap ignoring ECMA-262 §9.5.9 `Receiver`, letting `Object.create(hostObj)` children and `Reflect.set(hostObj, k, v, custom)` writes leak onto the host object (write-channel → RCE).\r\n- **GHSA-m5q2-4fm3-vfqp** — Cross-realm `Symbol.for` namespace leak + missing dangerous-symbol guards on the bridge's write traps (`set` / `defineProperty` / `deleteProperty`), enabling sandbox-installed `nodejs.util.promisify.custom` / stream brand / webstream hooks on host objects (RCE).\r\n- **GHSA-v6mx-mf47-r5wg** — Host prototype mutation via `Function.prototype.{call,apply,bind}` and `Reflect.{apply,construct}` indirection through `Object.prototype.__proto__` setter, severing host intrinsic prototype chains and escaping via `thisEnsureThis` proto-walk fallthrough (RCE).\r\n- **GHSA-q3fm-4wcw-g57x** — Defense Invariant #11 violation in `defaultSandboxPrepareStackTrace` (second variant of GHSA-9qj6-qjgg-37qq in a different file): sandbox-installed `Array.prototype[N]` setter / `Array.prototype.join` override could observe bridge-internal stack-trace state.\r\n- **GHSA-76w7-j9cq-rx2j** — Promise species hijack in `localPromise`'s swallow-tail, hijacking the downstream child constructor to capture V8's internal `(resolve, reject)` capability and reach a raw host-realm error → host `Function` (RCE).\r\n- **GHSA-m4wx-m65x-ghrr** — NodeVM constructor patch bypass of GHSA-8hg8-63c5-gwmx: any truthy `nesting` paired with a non-real-config `require` produced a NESTING_OVERRIDE-only resolver → inner NodeVM with attacker-chosen `require` → `child_process` RCE.\r\n- **GHSA-6j2x-vhqr-qr7q** — WebAssembly JSPI (`WebAssembly.promising` / `WebAssembly.Suspending`, Node 24+ behind a flag, Node 26+ default) producing Promise objects with a host-realm `[[Prototype]]` chain and no bridge interposition; species hijack delivers a raw host-realm rejection to sandbox `.catch` → host `Function` (RCE).\r\n- **GHSA-rp36-8xq3-r6c4** — NodeVM builtin denylist bypass via `process` (whose `getBuiltinModule(name)` reloads any core module regardless of allow/deny config) and `inspector/promises` (whose `Session().post('Runtime.evaluate', ...)` evaluates attacker JS in the host realm). Supersedes GHSA-947f-4v7f-x2v8.\r\n- **GHSA-r9pm-gxmw-wv6p** — NodeVM `builtin: ['*']` wildcard exposing Node's undocumented underscored network builtins (`_http_client`, `_http_server`, `_tls_*`, `_stream_*`) even when the documented `-http`/`-https`/`-net`/`-tls` exclusions were used — SSRF-class capability bypass (CVSS 8.6).\r\n- **GHSA-9g8x-92q2-p28f** — NodeVM builtin allowlist surfacing four process-wide observability builtins (`diagnostics_channel`, `async_hooks`, `perf_hooks`, `v8`) that read state of the entire host process rather than sandbox-local state — HTTP header / async-context / perf-mark / heap-snapshot exfiltration.\r\n\r\n## Documentation\r\n\r\n- [`docs/ATTACKS.md`](https://github.com/patriksimek/vm2/blob/main/docs/ATTACKS.md) extended through Category 35, plus two new Defense Invariants: **#12** (\"No sandbox-visible object has a host-realm prototype chain without bridge interposition\") and **#13** (\"The NodeVM builtin allowlist is a closed system\").\r\n\r\n## Upgrade Notes\r\n\r\n- **If you constructed `NodeVM({ nesting: <truthy> })` without an explicit `require` config object**, `new NodeVM(...)` now throws (GHSA-m4wx-m65x-ghrr). This covers every shape that previously silently produced a `vm2`-only resolver: omitting `require`, or setting it to any falsy value (`false`/`undefined`/`null`/`0`/`''`) or any truthy non-object value (`true`/number/string/symbol/function); and also any truthy `nesting` value, not only `nesting: true`. Either drop `nesting`, or pass an explicit `require` config object (e.g. `require: { builtin: [] }`) to acknowledge that vm2 will be requireable from inside the sandbox. The error message is actionable and links to the README hardening section.\r\n- **No other valid configurations are affected.** Embedders who explicitly listed any of `process` / `inspector` / `worker_threads` / `cluster` / `vm` / `repl` / `module` / `trace_events` / `wasi` / `diagnostics_channel` / `async_hooks` / `perf_hooks` / `v8` in `builtin` were already running an unsandboxed sandbox; those names now throw at load time and can be re-introduced as safe wrappers via `mock` / `override` / `SPECIAL_MODULES`.\r\n\r\n**Full Changelog**: https://github.com/patriksimek/vm2/compare/v3.11.3...v3.11.4\r\n"}