Media

vm2: External module allowlist uses a raw prefix test, so a prefix-sharing sibling package is treated as allowlisted

  • Publicada: 01.10.2026
  • Actualizado: 11.10.2026 10:22

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:

js
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:

js
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.

PlataformaPaqueteVersiones vulnerablesCorregida en
Paquete de npm vm2 < 3.11.7 3.11.7

Referencias

Puntuación CVSS 4.2/10
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.

Todas (78) en el archivo
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

  1. 2021: 1
  2. 2022: 4
  3. 2023: 7
  4. 2024: 0
  5. 2025: 0
  6. 2026: 66
Gravedad:
  1. Crítica · 10.0 CVE-2026-93605 < 3.12.1 3.12.1
  2. Crítica · 10.0 CVE-2026-100721 < 3.12.2 3.12.2
  3. Crítica · 10.0 CVE-2026-92955 < 3.11.8 3.11.8
  4. Crítica · 10.0 CVE-2026-92956 >= 3.10.1, < 3.11.7 3.11.7
  5. Crítica · 9.9 CVE-2026-92948 >= 3.9.6, < 3.11.7 3.11.7
  6. Crítica · 10.0 CVE-2026-92940 >= 3.11.3, < 3.11.7 3.11.7
  7. Crítica · 9.0 CVE-2026-92935 >= 3.11.4, < 3.11.7 3.11.7
  8. Crítica · 10.0 CVE-2026-92937 >= 3.11.6, < 3.11.7 3.11.7
  9. Crítica · 9.9 CVE-2026-92938 >= 3.11.3, < 3.11.7 3.11.7
  10. Crítica · 9.9 CVE-2026-92939 >= 3.11.3, < 3.11.7 3.11.7
  11. Crítica · 9.8 CVE-2026-92944 >= 3.10.2, < 3.11.7 3.11.7
  12. Crítica · 10.0 CVE-2026-92941 >= 3.11.3, < 3.11.7 3.11.7
  13. vm2: External module allowlist uses a raw prefix test, so a prefix-sharing sibling package is treated as allowlisted esta entrada
    Media · 4.2 CVE-2026-92945 < 3.11.7 3.11.7
  14. Alta · 7.5 CVE-2026-92961 < 3.11.6 3.11.6
  15. Crítica · 9.8 CVE-2026-47698 < 3.11.6 3.11.6
  16. Crítica · 9.8 CVE-2026-47210 < 3.11.4 3.11.4
  17. Crítica · 10.0 CVE-2026-47208 < 3.11.4 3.11.4
  18. Crítica · 10.0 CVE-2026-47131 < 3.11.4 3.11.4
  19. Crítica · 9.8 CVE-2026-45411 < 3.11.3 3.11.3
  20. Crítica · 9.8 CVE-2026-44009 < 3.11.2 3.11.2
Mostrar más (20) Mostrando 40 de 66

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.

Conectar tu aplicación
Newsletter DockRay

La seguridad de tus aplicaciones en tu correo

Vulnerabilidades importantes, recomendaciones concretas y consejos prácticos para tus aplicaciones. Elige tus tecnologías y sigue lo que importa para tu proyecto.

  • Un resumen diario de nuevas vulnerabilidades, también las críticas.
  • Avisos sobre actualizaciones importantes.
  • Consejos prácticos sobre seguridad y monitorización de aplicaciones.

Déjalo vacío para recibir avisos de todas las tecnologías.

Suscripción gratuita. Date de baja con un clic en cualquier correo.