CVE-2026-100721: Kritisk sandkasseflugt i vm2
Sikkerhedshul i vm2 (CVE-2026-100721) lader kode bryde ud af sandkassen og køre frit på værtssystemet. Opdatér til vm2 3.12.2.
Hvad er det?
vm2 er et javascript-bibliotek, som udviklere bruger til at køre upålidelig kode i en isoleret sandkasse, altså et afgrænset miljø adskilt fra resten af applikationen. CVE-2026-100721 er en fejl i den del af vm2, der kaldes NodeVM, og som styrer hvilke moduler kode i sandkassen må hente ind udefra. Fejlen ligger i, hvordan vm2 tjekker stien til tilladte moduler: den bruger et regulært udtryk uden krav om en fuld sti-afgrænsning, så et modul med et navn, der blot starter med samme tegn som et godkendt modul, kan glide igennem. Kode i sandkassen kan derfor kræve et modul, der aldrig var godkendt, og det kører med fulde rettigheder i værtsprogrammet, før vm2 når at lægge begrænsninger på det. Resultatet er en sandkasseflugt: kode, der skulle være isoleret, får i stedet fuld adgang til værtsmiljøet.
Hvem rammer det?
Det rammer virksomheder, der har udviklet eller driver Node.js-applikationer, som bruger vm2 til version før 3.12.2, og som konkret har konfigureret `require.external` med en tilpasset resolver og `context: ‘host’`. Det gælder typisk platforme, hvor brugere eller tredjeparter kan uploade og køre kode, eksempelvis plugin-systemer, online kodeeditorer, CI/CD-værktøjer eller SaaS-løsninger med scriptbare udvidelser. Almindelige webshops eller interne administrationssystemer uden brugerstyret kodekørsel er ikke berørt, medmindre de bygger på vm2 til dette formål.
Hvad kan ske?
En angriber, der kan få sin kode kørt inde i sandkassen, kan bryde ud og opnå kodekørsel med samme rettigheder som selve serverprocessen. I praksis betyder det adgang til filsystem, miljøvariabler, database-forbindelser og andre systemer, serveren kan tilgå. For en dansk virksomhed, der driver en platform med brugerindsendt kode, kan det føre til datatyveri, installation af skadelig software eller at angriberen bruger serveren som springbræt videre ind i det interne netværk.
Hvor alvorligt er det?
CVSS-score er 9,0 ud af 10, kritisk. Sårbarheden kræver ikke login eller nogen handling fra en bruger uden for sandkassen, men den forudsætter, at angriberen allerede kan få kode udført inde i sandkassen, og at driften har konfigureret den specifikke resolver-funktion. Angrebskompleksiteten er sat til høj, fordi det kræver kendskab til modulstier og sandkassens opsætning. Der er ikke belæg for, at sårbarheden bliver udnyttet i praksis på offentliggørelsestidspunktet, men den tekniske beskrivelse er detaljeret nok til, at et angreb kan udvikles relativt hurtigt.
Hvad gør jeg nu?
Følgende trin lukker hullet og begrænser skaden, hvis I bruger vm2 i jeres applikationer:
- Opdatér vm2 til version 3.12.2 eller nyere i alle projekter og afhængigheder, hvor biblioteket indgår.
- Gennemgå jeres kodebase for brug af vm2 og NodeVM, herunder indirekte via tredjepartsbiblioteker, så I kender det fulde omfang.
- Tjek om I bruger `require.external` med en tilpasset resolver og `context: ‘host’`, og stram i så fald listen over tilladte moduler, indtil opdateringen er på plads.
- Gennemgå logs for uventet modulindlæsning eller uforklarlig kodekørsel i den periode, sårbarheden har eksisteret.
- Overvej på sigt at erstatte vm2 med en aktivt vedligeholdt isolationsløsning, da vm2-projektet historisk har haft flere lignende sandkasseflugter.
- Hent hjælp udefra, hvis I ikke selv kan verificere, om jeres platform bruger den sårbare konfiguration, eller hvis I finder tegn på misbrug.
Opdatér inden for 7 dage
Vi anbefaler, at I straks kortlægger, om jeres Node.js-applikationer bruger vm2 og i givet fald opdaterer til 3.12.2 eller nyere. Er vm2 kun brugt uden den specifikke resolver-konfiguration, kan opdateringen planlægges inden for en uge uden akut risiko. Kører I derimod en platform, hvor tredjeparter kan indsende og eksekvere kode, bør opdateringen prioriteres højt, da konsekvensen ved misbrug er fuld kompromittering af værtssystemet.
Tidslinje
Konkrete eksempler
Plugin-baseret SaaS-platform
En dansk SaaS-virksomhed lader kunder uploade tilpassede scripts, der køres i en vm2-sandkasse på deres servere. En kunde med onde hensigter udnytter fejlen til at bryde ud af sandkassen og får adgang til andre kunders data på samme server. Da vm2-versionen er før 3.12.2, og resolveren er konfigureret som beskrevet, lykkes udbruddet uden at kræve login til selve serveren.
Ofte stillede spørgsmål
Er vi ramt af denne sårbarhed?
I er kun ramt, hvis jeres applikation bruger vm2-biblioteket i en version før 3.12.2 til at sandboxe upålidelig kode, og specifikt hvis I har konfigureret `require.external` med en tilpasset resolver og `context: ‘host’`. Brug af vm2 uden denne konfiguration er ikke berørt af netop denne fejl.
Hvordan tjekker vi, om vm2 indgår i vores systemer?
Søg efter ‘vm2’ i jeres package.json-filer og lås-filer (package-lock.json, yarn.lock) på tværs af alle Node.js-projekter. Bed også jeres udviklere eller leverandør bekræfte, om biblioteket bruges direkte eller via en afhængighed.
Kan vi vente med opdateringen til en planlagt driftsvindue i weekenden?
Hvis I bruger den sårbare konfiguration og lader eksterne brugere køre kode i sandkassen, bør I ikke vente. Er brugen af vm2 mere begrænset og internt kontrolleret, kan opdateringen med rimelighed vente til næste planlagte vedligeholdelsesvindue.
Skal vi anmelde hændelsen til myndighederne?
Der er tale om en sårbarhed, ikke en konstateret hændelse. Finder I tegn på, at sårbarheden er blevet udnyttet, og at persondata er kompromitteret, skal I vurdere anmeldepligt efter databeskyttelsesforordningen over for Datatilsynet.
Hvad hvis vi ikke selv har skrevet den kode, der bruger vm2?
Kontakt jeres leverandør eller udviklingspartner og bed dem bekræfte, hvilken version af vm2 der anvendes, og om opdateringen til 3.12.2 er implementeret.
CVSS-detaljer
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:C/C:H/I:H/A:H
CWE-svaghedstyper
Original NVD-beskrivelse (engelsk)
vm2 before 3.12.2 contains an authorization bypass in the NodeVM external-module resolver. When an embedder configures `require.external` with a custom resolver (and `context: ‘host’`), `LegacyResolver.customResolve` in lib/resolver-compat.js records the resolved module directory in `this.externals` as `new RegExp(‘^’ + escapeRegExp(resolvedPath))`, without requiring a path separator or end-of-string boundary. Untrusted guest code can therefore require the allowlisted module (e.g. `foo`) and then require the absolute path of a non-allowlisted sibling whose path merely shares the resolved prefix (e.g. `…/node_modules/foo2/index.js`); the sibling passes `isPathAllowedForModule` and is loaded through `hostRequire`, so its top-level code runs in the host process before the exports are wrapped with `vm.readonly`, resulting in a sandbox escape and arbitrary code execution in the host context.
Referencer & kilder
Eksterne kilder
Brug for hjælp med jeres sikkerhed?
Vi hjælper SMV’er med at omsætte trusler som denne til konkrete handlingsplaner.