Ce mail provient de l'extérieur, restons vigilants ===================================================================== CERT-Renater Note d'Information No. 2026/VULN881 _____________________________________________________________________ DATE : 10/09/2026 HARDWARE PLATFORM(S): / OPERATING SYSTEM(S): Systems running vm2 versions prior to 3.12.2. ===================================================================== https://github.com/patriksimek/vm2/releases https://github.com/patriksimek/vm2/security?page=1 _____________________________________________________________________ v3.12.2 Latest @patriksimek patriksimek released this v3.12.2 a0139cf Three advisories closed, and vm2 can now be shipped by single-file bundlers. Patch release — no API changes, with observable behaviour changes for host buffers and host promises handed to the sandbox (see Upgrade Notes). What's Changed Security fixes GHSA-5h3f-q97h-ccvc — a NodeVM with a custom require.resolve recorded each resolver answer as a raw string prefix, so resolving an allowlisted package authorized every prefix-sharing sibling beside it (.../node_modules/foo authorized .../node_modules/foo2/index.js), and the {module, path} return shape authorized the whole search directory; under the default context: 'host' the sibling's top-level code ran with host authority. Resolver answers are now recorded as boundary-matched base paths (plus exact extension spellings for extension-probed answers), the object shape authorizes only the resolved package's directory, and an authorization is withdrawn again when its load finds nothing. GHSA-2v2p-6j97-cjg9 — a host promise reaching the sandbox through a constructor return (new HostFn()), a host getter or data property, or a callback argument carried no rejection reaction, so sandbox code that simply dropped it terminated the host process under Node's unhandledRejection policy; the GHSA-gjq8 fix had covered only apply returns. Every host promise is now marked handled once at the single host→sandbox delivery chokepoint (a cheap prototype brand check that never invokes .then on non-promises and recognises promises from a second host realm), and the construct trap carries the same unconditional mark as apply. The sandbox still observes rejections through its own sanitized .catch. GHSA-489w-w794-jq94 — a host-allocated Buffer (a builtin's return value such as zlib.deflateSync, an embedder-supplied buffer, a callback argument) exposed Node's shared 64 KiB allocation pool through .buffer or its legacy twin .parent, letting the sandbox read and overwrite unrelated host buffers — host memory disclosure and corruption. The GHSA-fcqc backing-store ownership rule now applies at the bridge for every host view, keyed on the identity of the delivered value so every alias of the store is covered by one rule; the raw buffer / parent / offset getters are no longer deliverable, the gate fails closed if the bridge cannot resolve ArrayBuffer.isView, and a foreign store planted on a view is refused. Fixed Single-file bundlers (Bun compile, esbuild, pkg, ...) can now ship vm2. The sandbox bootstrap files had to be read from disk at runtime, so a compiled binary failed with ENOENT as soon as the package directory was not on disk. They are now embedded as string literals in the generated lib/sources.js, and the sandbox-compiled scripts use a fixed virtual filename so bootstrap frames stay redacted from sandbox-visible stack traces. Maintenance Dev dependency @humanfs/node bumped from 0.16.6 to 0.16.8. Documentation Categories 46 (custom-resolver sibling authorization, with two documented residuals), 22 (host promises on every delivery route) and 41 (host views and the shared pool, with the observable behaviour changes and two documented residuals) are extended in docs/attacks/, with matching rows in the "How The Bridge Defends" table. Upgrade Notes Host buffers that do not own their whole backing store are delivered bounded. For such a view, .buffer / .parent is an exact-size copy (not identity-stable, not write-through), and byteOffset / offset read as 0 so Buffer.from(v.buffer, v.byteOffset, v.length) keeps working. Sub-views the sandbox creates from a host-backed buffer lose .buffer aliasing with their parent (index writes still alias), and SharedArrayBuffer sub-views are delivered as copies — hand over a view spanning the whole store for live sharing. Buffers that own their store (Buffer.alloc(n), large buffers) are unchanged. Ignored host promises are silent on every route. Embedders no longer see unhandledRejection for a host promise handed to the sandbox through a getter, callback argument or constructor return, exactly as for call returns since GHSA-gjq8; attach an explicit .catch() to debug rejections. A custom resolver's {module, path} answer must name a package inside path. A module that is absolute, relative or contains .. is now refused and reports module-not-found; return the string shape to name a path directly. Bundling: nothing to configure — lib/sources.js is part of the published package. If you patch a bootstrap file in a fork, run npm run build:sources (or npm test, which regenerates it) so the embedded copy does not go stale. No other valid configurations are affected. Full Changelog: v3.12.1...v3.12.2 ========================================================= + CERT-RENATER | tel : 01-53-94-20-44 + + 23/25 Rue Daviel | fax : 01-53-94-20-41 + + 75013 Paris | email:cert@support.renater.fr + =========================================================