Omkring 09.00 UTC tog angriparen kontroll över Jared Wrays GitHub-konto. Med den åtkomsten kunde angriparen lägga till kod direkt i main-grenen i keyv-projektet och omedelbart skapa nya versioner av paket i keyv- och cacheable-familjerna .
Den första spridningsvågen omfattade 11 paket i de två namnrymderna. Bland dem fanns keyv, cacheable-request, cache-manager, @cacheable/utils, flat-cache och file-entry-cache . Aikido Security, StepSecurity, Socket och Chainguard bekräftade intrånget oberoende av varandra under attackens första timmar .
De manipulerade paketen följde i stort sett samma mönster. Två filer lades till:
setup.mjsMath_Symbol.jsDessutom ändrades package.json så att det innehöll en automatisk installations-hook: "preinstall": "node setup.mjs" .
Det innebar att setup.mjs kördes när en utvecklare eller ett byggsystem installerade en berörd version med npm install. Skriptet fungerade som en så kallad dropper: det laddade ned en legitim binär för JavaScript-körmiljön Bun från GitHub Releases och använde den för att starta den kraftigt fördunklade andrastegslasten Math_Symbol.js, som var omkring 710–728 kilobyte stor .
Microsoft Threat Intelligence har klassificerat lasten som en Mini Shai-Hulud-variant . Den letade efter ett brett spektrum av hemligheter och åtkomstuppgifter, bland annat :
Det som gjorde attacken särskilt allvarlig var att den inte stannade i den ursprungliga paketfamiljen. Efter att ha stulit npm-token med publiceringsrättigheter och GitHub-PAT från den infekterade miljön använde masken åtkomsten för att publicera manipulerade versioner av paket som tillhörde andra, oberoende underhållare .
Omfattningen växte snabbt:
Masken korsade alltså gränserna mellan namnrymder. Den spred sig inte bara bland keyv och cacheable, utan nådde även paket kopplade till bland andra Deliveroo, Ornikar, OneReach, Picsart, Qlik och ServiceTitan .
De stulna uppgifterna exfiltrerades till ett GitHub-repositorium som kontrollerades av angriparen. Enligt analyserna kunde skadeprogrammet skapa ett nytt repositorium eller använda ett särskilt repositorium för att samla in materialet .
Lasten hade dessutom flera redundanta kanaler för dataexfiltrering . Det gjorde kampanjen mer motståndskraftig: även om en enskild kanal stängdes kunde andra fortfarande fungera.
Säkerhetsforskare rekommenderade att alla system som hade kört en berörd paketversion skulle behandlas som fullt komprometterade. Det räcker alltså inte att bara radera de skadliga filerna.
Pinna berörda paket till kända rena versioner eller rulla tillbaka till versioner från före incidenten. Använd vid behov overrides i package.json för npm, Yarn eller pnpm, så att en komprometterad version inte installeras på nytt av misstag .
Kontrollera också lockfilerna package-lock.json, yarn.lock och pnpm-lock.yaml. Granskningen måste omfatta transitiva beroenden, alltså paket som projektet använder indirekt .
En dator, byggserver eller CI/CD-körmiljö där npm install kördes mot en berörd version bör betraktas som fullt exponerad . Radera inte bara skadeprogrammet och fortsätt använda systemet som vanligt – hemligheter som fanns tillgängliga där kan redan ha kopierats.
Återkalla och skapa nya uppgifter för allt som kan ha varit åtkomligt från den infekterade miljön . Det gäller bland annat:
En viktig detalj är att skadeprogrammet i vissa fall skapade GitHub Actions- eller workflow-bevakare som kunde fånga upp och exponera en ny token direkt när den skapades . Säkerhetsforskare rekommenderade därför att sådana bevakare eller övervakningstjänster stängs av och tas bort innan hemligheterna roteras .
Rensa npm-, pnpm- och Yarn-cachar på både utvecklardatorer och CI/CD-körmiljöer. Rensa även Docker-byggcachar . Bygg därefter om artefakter från rena miljöer, så att manipulerade beroenden inte lever kvar i cachelagrade byggsteg eller Docker-lager .
Leta efter nyligen skapade repositorier, obehöriga arbetsflöden och misstänkta commits . Kontrollera även om beständighetsfiler som .claude/settings.json eller .vscode/tasks.json har lagts till . Gå igenom åtkomstloggar och kontrollera vilka token, arbetsflöden och byggsystem som kan ha påverkats.
Shai-Hulud-incidenten visar hur ett enda kapat underhållarkonto kan få konsekvenser långt utanför ett enskilt projekt. Genom att utnyttja npm:s installationsskript, en legitim Bun-binär och stulna publiceringsuppgifter kunde angriparna förvandla ett första intrång till en kedjereaktion över hela ekosystemet .
För utvecklings- och säkerhetsteam är lärdomarna tydliga: lås beroenden till verifierade versioner, begränsa eller stäng av pre- och postinstall-skript där det är möjligt, bevaka ovanlig aktivitet i GitHub och ha en färdig handlingsplan för incidenter i mjukvaruförsörjningskedjan.