En kapret version af et populært npm-værktøj gik i sidste uge målrettet efter noget, ingen supply chain-orm har jagtet før: konfigurationsfilerne til Claude Desktop, Cursor og Windsurf, hvor API-nøgler og MCP-server-credentials ligger i klartekst.
Pakken hedder jscrambler, den blev kapret 11. juli, og Socket fangede den 6 minutter efter. De 6 minutter var ikke nok. Her er hvad der skete, hvorfor det rammer alle der kører AI-kodeværktøjer med MCP, og hvad du skal rotere nu.
jscrambler er et JavaScript-beskyttelsesværktøj. Det obfuskerer og hærder klient-side kode, det kører på build-tidspunktet, og det henter omkring 15.800 downloads om ugen. Med andre ord blev et værktøj, hvis eneste opgave er at beskytte kode, vektoren for at stjæle den.
Den 11. juli klokken 16:12 britisk tid dukkede den første kaprede version, 8.14.0, op på npm. Angriberen brugte et stjålet npm publishing-credential, ikke et hul i selve produktet. Der er ingen matchende commits i det offentlige GitHub-repo, fordi koden aldrig gik gennem den normale udgivelsesvej. Den blev skudt direkte ind i registret.
Det er en kendt, men ubehagelig klasse af angreb. Du reviewer din egen kode, men du reviewer sjældent den kode, dine afhængigheder trækker ind, og slet ikke i sekundet den installeres. Det er præcis det hul, angrebet lever i.
Angrebet var ikke en enkelt handling. Det var en angriber, der sad og tilpassede sig, mens forsvaret reagerede, og det er præcis derfor det er værd at studere.
Klokken 16:12 britisk tid den 11. juli landede 8.14.0. Socket fangede den 6 minutter senere, på en størrelsesstigning fra omkring 38 KB til 7,9 MB plus en ny preinstall-hook. I stedet for at trække sig publicerede angriberen i de næste 3 timer fire nye versioner, 8.16.0, 8.17.0, 8.18.0 og 8.20.0, og ændrede leveringsmetoden undervejs. Version 8.15.0, udgivet ind imellem de to første, var ren og hører ikke med til angrebet.
Jscrambler nåede at deprecate de kaprede versioner og udgive en ren 8.22.0 omkring 2 timer efter starten. Det aktive vindue var altså kort. Men en infostealer skal ikke bruge dage, den skal bruge de sekunder, en npm install tager. Angrebet ramte også fire afhængige plugins, jscrambler-webpack-plugin, gulp-jscrambler, grunt-jscrambler og jscrambler-metro-plugin, som alle blev deprecated og erstattet. Hvis du bruger et af dem i stedet for hovedpakken, er du lige så eksponeret.
Selve nyttelasten er en Rust-baseret infostealer, der høster bredt. Men det, der gør netop dette angreb værd at forstå, er hvad den gik efter ud over det sædvanlige. Den gennemsøgte konfigurationsfilerne til AI-kodeværktøjer, og det er en ny kategori af mål.
Listen er præcis de værktøjer, danske udviklingsteams bruger lige nu: Claude Desktop, Cursor, Windsurf, Factory, Zed og VS Code. Filerne den ledte efter indeholder API-nøgler, endpoints og auth-tokens til MCP-servere. MCP er protokollen, dine AI-agenter bruger til at koble sig på eksterne systemer, og konfigurationsfilerne er der, hvor nøglerne til de forbindelser bor.
Oveni gik malwaren efter det klassiske: cloud-tokens fra AWS, Google Cloud og Azure, crypto-wallets, browser-sessions, password-vaults som Bitwarden og 1Password, samt npm- og GitHub-tokens. Men MCP-delen er det nye, og det er den, der gør angrebet relevant for enhver, der bygger AI ind i sin drift.
For at forstå, hvorfor de her filer er så værdifulde for en angriber, skal man se på, hvad en MCP-server faktisk er. Den er en bro mellem AI-modellen og et rigtigt system, og konfigurationsfilen holder nøglerne til den bro.
Tag en typisk opsætning i en dansk virksomhed. Du kan have MCP-servere til dit CRM, til Microsoft 365, til dit økonomisystem og til et par interne værktøjer. Én JSON-fil kan liste dem alle sammen, hver med sit endpoint og sit token. Det er ikke én lækket API-nøgle. Det er kortet over hele din integrationsflade plus nøglerne til at åbne den.
Oveni kommer, at tokens til MCP-servere ofte er langlivede og bredt scopede, fordi det er det, der gør agenten brugbar i det daglige. En agent, der skal kunne slå op i og skrive til dit CRM, har brug for adgang, der rækker langt. Når den adgang ligger i en fil i klartekst, er sprængradius ikke ét system, men alt agenten kunne nå. Det er forskellen på at tabe en enkelt nøgle og at tabe nøgleknippet med kortet til bygningen. En stærk datasikkerhed i AI-opsætninger begynder derfor ved, hvordan de her nøgler opbevares.
Her bliver tidslinjen vigtig. npm 12 udkom 8. juli, 3 dage før angrebet, og den gjorde install-scripts slået fra som standard. De første kaprede versioner, 8.14.0 til 8.17.0, brugte en klassisk preinstall-hook, altså et script der kører automatisk under installation. Havde du opdateret til npm 12, blev du beskyttet ved et rent tilfælde, fordi hooken aldrig kørte.
Angriberen tilpassede sig på under 3 timer. I version 8.18.0 og 8.20.0 blev preinstall-hooken fjernet, og dropperen flyttet ind i pakkens hovedkode som en selveksekverende funktion. Nu kører malwaren, når pakken importeres eller dens CLI kaldes, og en installation der springer scripts over stopper den ikke længere. Nyttelasten var byte-for-byte identisk på tværs af alle versionerne. Kun leveringen ændrede sig.
Lektien er ubehagelig men vigtig. At blokere install-scripts er en reel forbedring, og npm 12 er et skridt frem. Men det uløste problem er ikke install-hooks. Det er, at et stjålet maintainer-credential stadig lader en angriber sende kode, der kører, når din software kører. Ingen toggle løser det.
JFrog, der analyserede de samme 5 versioner, identificerede nyttelasten som IronWorm, en Rust-infostealer de dokumenterede en måned tidligere, og koblede den til Shai-Hulud-slægten af selvspredende npm-angreb. For den her malware stjæler ikke bare. Den er bygget til at brede sig.
Mekanikken er enkel og effektiv. Den leder efter npm-tokens i miljøvariabler og filer, tjekker dem mod registret, vælger pakker med høje downloadtal, injicerer sin egen preinstall i deres tarballs og publicerer de inficerede versioner direkte. En stjålet token bliver til næste angreb. Oveni kører den en eBPF-komponent i Linux-kernen, har anti-debug på Windows og macOS, etablerer persistence via en scheduled task eller en LaunchAgent, og sender data ud over Tor plus bulk til den offentlige filhost temp.sh.
En detalje er værd at hæfte sig ved. Malwaren gik også efter installationsmapperne for red-team-frameworks som Metasploit, Sliver og Havoc. Med andre ord sigtede den bevidst på sikkerhedsfolk og penetrationstestere. Det er ikke tilfældig bred høst, det er målrettet.
Jscrambler oplyser, at npm rapporterer omkring 1.500 downloads af de kaprede versioner, og bruger i nogle udmeldinger formuleringen zero confirmed downloads. De to ting modsiger ikke hinanden, og forskellen er værd at forstå.
Nul bekræftede er ikke det samme som nul. npm's downloadtal halter med timer og er stadig ved at blive verificeret, så nul bekræftede betyder blot, at den forsinkede telemetri endnu ikke har bekræftet nogen. Jscramblers forensiske undersøgelse er stadig i gang, og det fulde omfang af berørte maskiner er ukendt.
Den praktiske konsekvens er enkel. Vent ikke på et bekræftet tal, før du handler. Hvis en kapret version rørte en maskine, gør antagelsen om tyveri dig ikke fattigere, men at vente kan gøre dig meget fattigere. En stealer arbejder i sekunderne efter installation, længe før downloadtallene falder på plads.
Start med at afklare eksponering. Kør npm ls jscrambler, og gennemsøg alle lockfiles og CI-logs fra 11. juli og frem for versionerne 8.14.0, 8.16.0, 8.17.0, 8.18.0 og 8.20.0. Husk de fire plugins. Tjek transitive dependencies, og led efter filerne dist/intro.js og dist/setup.js i node_modules. Jscramblers egen advisory nævner kun 4 af de 5 versioner og udelod 8.18.0, så behandl alle 5 som mistænkte.
Hvis en kapret version kørte på en maskine, så antag tyveri, ikke eksponering. Roter alt, stealeren kunne nå: MCP-nøgler og API-tokens til dine servere, npm- og GitHub-tokens, cloud-nøgler, samt browser-, Slack- og Discord-sessions. Flyt crypto til en ny wallet på en ren maskine. Tjek for persistence i Task Scheduler på Windows og i LaunchAgents på macOS. Opgrader derefter til jscrambler 8.22.0 eller nyere, eller pin til den rene 8.13.0.
Og så det forebyggende. Brug npm 12 eller approve-scripts til at kontrollere scripts, og overvej et værktøj til real-time detektion. Men vigtigst: flyt dine MCP-credentials ud af rå JSON-filer og ind i OS-keychain eller en secret manager, hvor det kan lade sig gøre. En konfigurationsfil i klartekst er præcis det, den her type malware leder efter først.
Zoom til sidst ud. Det her er fjerde gang i 2026, at en legitim, meget brugt npm-pakke er blevet kapret via et stjålet credential. Mønsteret er det samme hver gang: vælg et værktøj udviklere stoler på, ram udgivelseskontoen, send koden ud før detektion.
Angrebet udnyttede ikke et hul i Jscramblers produkt. Det udnyttede distributionskanalen, den del kunderne hverken kan se eller kontrollere. Ethvert værktøj du installerer, om det er en npm-pakke, en SDK eller et sikkerhedsprodukt, arver din tillid og din adgang. Det er ikke et sidespor, det er hele pointen.
For alle, der bygger på MCP, betyder det, at credential-hygiejne holder op med at være en engangsopgave og bliver en driftsdisciplin. Zero trust betyder her, at hverken en leverandørs løfte eller en konfigurationsfil du selv skrev, er en kontrol i sig selv. Dine nøgler ligger spredt i et dusin værktøjers konfigurationer, og den eneste holdbare antagelse er, at enhver af dem kan blive læst.