vm2: External module allowlist uses a raw prefix test, so a prefix-sharing sibling package is treated as allowlisted
Summary
isPathAllowedForModule decides whether a resolved path belongs to an allowlisted external module using a raw string prefix test. node_modules/foo2 starts with node_modules/foo, so a package whose name merely shares a prefix with an allowlisted one is treated as being inside it, and a relative require from the allowlisted package reaches it even with transitive loading disabled.
Where it is
lib/resolver-compat.js, lines 122 to 132, quoted from HEAD 7a1f5100b96f48d34e0fe104ab37c0acc5944f92:
isPathAllowedForModule(path, mod) {
if (!super.isPathAllowed(path)) return false;
if (mod) {
if (mod.allowTransitive) return true;
if (path.startsWith(mod.path)) {
const rem = path.slice(mod.path.length);
if (!/(?:^|[\\/])node_modules(?:$|[\\/])/.test(rem)) return true;
}
}
return this.externals.some(regex => regex.test(path));
}
With mod.path of .../node_modules/foo and a resolved path of .../node_modules/foo2/index.js, startsWith is true and rem is 2/index.js, which contains no node_modules segment, so the function returns true.
The node_modules test in rem is what stops a genuine transitive dependency from slipping through. It does not stop a sibling, because a sibling's remainder never contains that segment.
Impact
Code running in NodeVM under an external module allowlist with transitive: false can reach a package that was not allowlisted, provided an allowlisted package performs a relative require to a prefix-sharing sibling.
Two preconditions are worth stating plainly rather than leaving implicit. The deployment must already have such a package layout, and an allowlisted package must have a reachable code path that does the relative require. This is not something the attacker creates; it is something they find. That narrows it considerably, and it is why I have not scored it higher.
Reachability
NodeVM.run at lib/nodevm.js:506 executes the script. require comes from createRequireForModule at lib/setup-node-sandbox.js:168-172 and reaches the resolver callback at lib/nodevm.js:380-384. LegacyResolver.resolveFull at lib/resolver-compat.js:145-160 sets currMod for direct requires, the relative specifier resolves through DefaultResolver.resolveFull and tryFile at lib/resolver.js:327-330, and the authorization decision lands on the function above.
Suggested fix
Require a separator after the prefix, so a sibling cannot match:
if (path === mod.path || path.startsWith(mod.path + path.sep)) {
That is the same anchoring the rem regex already applies to node_modules, applied one level earlier.
Betroffene Software
Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.
| Plattform | Paket | Anfällige Versionen | Behoben in |
|---|---|---|---|
| npm-Paket | vm2 | < 3.11.7 | 3.11.7 |
Verweise
- https://github.com/patriksimek/vm2/security/advisories/GHSA-7q3f-wx44-378m
- https://nvd.nist.gov/vuln/detail/CVE-2026-92945
- https://github.com/patriksimek/vm2/commit/6ac3916da84e060c403e407b6b6318fcc66b0e72
- https://github.com/patriksimek/vm2
- https://github.com/patriksimek/vm2/releases/tag/v3.11.7
- https://www.vulncheck.com/advisories/vm2-before-3.11.7-module-allowlist-bypass-via-prefix-matching
- CVSS-Vektor
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N- Schwäche (CWE)
CWE-22, CWE-863- Plattform
- npm
- Paket
vm2- Veröffentlicht
- 01.10.2026
- Aktualisiert
- 11.10.2026 10:22
Quellen und Lizenzen
OSV / GitHub Advisory Database - GHSA-7q3f-wx44-378m - CC BY 4.0
Schwachstellenhistorie: vm2
Alle veröffentlichten Schwachstellen dieses Pakets (npm-Paket), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.
- Einträge insgesamt
- 78
- Erste → letzte
- 10.2021 10.2026
- Ohne Fix
- 1
- In Angriffen ausgenutzt
- 0
Verteilung nach Schweregrad
- Kritisch 51
- Hoch 14
- Mittel 12
- Niedrig 1
Veröffentlichungen pro Jahr
- 2021: 1
- 2022: 4
- 2023: 7
- 2024: 0
- 2025: 0
- 2026: 66
-
vm2: External module allowlist uses a raw prefix test, so a prefix-sharing sibling package is treated as allowlisted dieser Eintrag
Erkennen Sie Schwachstellen in Ihrer Anwendung
Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.