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.
Software afectado
Haz clic en una tecnología para ver todas sus vulnerabilidades.
| Plataforma | Paquete | Versiones vulnerables | Corregida en |
|---|---|---|---|
| Paquete de npm | vm2 | < 3.11.7 | 3.11.7 |
Referencias
- 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
- Vector CVSS
CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:N- Debilidad (CWE)
CWE-22, CWE-863- Plataforma
- npm
- Paquete
vm2- Publicada
- 01.10.2026
- Actualizado
- 11.10.2026 10:22
Fuentes y licencias
OSV / GitHub Advisory Database - GHSA-7q3f-wx44-378m - CC BY 4.0
Historial de vulnerabilidades: vm2
Todas las vulnerabilidades publicadas de este paquete (Paquete de npm), de la más reciente a la más antigua. Muestra si es un fallo aislado o un paquete que hay que vigilar.
- Entradas en total
- 78
- Primera → última
- 10.2021 10.2026
- Sin corrección
- 1
- Explotada en ataques
- 0
Distribución por gravedad
- Crítica 51
- Alta 14
- Media 12
- Baja 1
Divulgaciones por año
- 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 esta entrada
Identifica las vulnerabilidades de tu aplicación
Con la integración de DockRay y el inventario de software activado, DockRay compara las versiones notificadas de los componentes con las vulnerabilidades conocidas y avisa de las coincidencias confirmadas. La cobertura depende de la tecnología compatible y de los avisos disponibles.