Den 4 augusti 2026 drabbades npm-ekosystemet av en sofistikerad attack mot programvarans leveranskedja, kallad ChainDrop, efter att GitHub-kontot tillhörande en underhållsansvarig för de populära open source-paketen Keyv och Cacheable hade komprometterats . Den resulterande självförökande masken spred sig till över 2 251 versioner av 452 unika paket med cirka 2 miljarder nedladdningar per månad, vilket drabbade organisationer som Deliveroo, Ornikar, OneReach, Picsart, Qlik och ServiceTitan.

Keyv är ett enkelt nyckel-värde-lager för Node.js med stöd för flera backends, medan Cacheable är dess underliggande HTTP-cache-ramverk. Tillsammans fungerar dessa paket som en grundläggande cachinginfrastruktur i hela JavaScript-ekosystemet. Båda paketen underhålls av samma utvecklare, vars GitHub-konto komprometterades av hotaktören.

Angriparen publicerade den första skadliga versionen, keyv@6.0.0, omkring kl. 09:00 UTC den 4 augusti 2026. Skadlig programvaran är en avkomma till ”Mini”-familjen Shai-Hulud, men tillskrivningen till TeamPCP är fortfarande obekräftad. Masken spred sig snabbt genom att samla in npm- och GitHub-token från komprometterade miljöer och använda dem för att publicera ytterligare förgiftade versioner. Socket verifierade 2 251 förgiftade versioner i 452 paket.

Nyttolasten stjäl ett omfattande urval av känslig data, inklusive inloggningsuppgifter för molntjänster, CI/CD-hemligheter, utvecklartoken, AI-konfigurationsfiler och kryptovalutaplånböcker. Den planterar även Claude Code- och Visual Studio Code-hooks för kontinuerlig IDE-baserad körning. Inga CVE-identifierare har tilldelats denna kampanj vid tidpunkten för skrivandet.

 

Översikt över sårbarheter

Initial åtkomst

Hotaktören komprometterade GitHub-kontot för Keyv-underhållaren, vilket gav direkt push-åtkomst till källkodsrepositorierna för Keyv, Cacheable, cache-manager, flat-cache, file-entry-cache och ett stort antal relaterade paket inom underhållarens monorepo.

Skadlig publicering

Från och med kl. 09:00 UTC införde angriparen IDE-persistenspayloads i Keyv-repositoriet och publicerade därefter keyv@6.0.0 samt efterföljande skadliga versioner. Eftersom paketen byggdes och publicerades via deras legitima GitHub Actions-arbetsflöden innehöll de komprometterade utgåvorna giltig SLSA-ursprungsinformation, vilket gjorde att integritetsverifieringskontrollerna kunde kringgås. Varje förgiftat paket innehöll en post ”preinstall”: ”node setup.mjs” i sin package.json, vilket ledde till att dropparen kördes automatiskt innan någon npm-installation hade slutförts.

Spridning av masken

Malwarens förmåga att sprida sig själv gjorde det möjligt för den att infektera paket som tillhörde andra underhållare vars projekt var beroende av ett tidigare komprometterat paket. Genom att samla in giltiga npm-publiceringstoken från CI/CD-körare och utvecklares arbetsstationer publicerade masken nedströms-paket på nytt med den skadliga nyttolasten injicerad, vilket skapade en kaskadkedja av komprometteringar. Denna mekanism gjorde det möjligt för attacken att undkomma det ursprungliga Keyv/Cacheable-namnområdet och sprida sig över organisationsgränser.

Drabbade paket

De viktigaste komprometterade paketen var:

Paketnamn

Skadliga drabbade versioner

Verifierat säkert / Återställd ren version

keyv

6.0.0 (och efterföljande skadliga versioner)

5.6.0

flat-cache

6.1.24

6.1.23

fil-post-cache

11.1.6

11.1.5 (eller tidigare stabil version)

cacheable-request

13.0.20

13.0.19 (eller tidigare stabil version)

cache-manager

7.2.10

7.2.9

cacheable

2.5.1

2.5.0 (eller tidigare stabil version)

@cacheable/utils

2.5.1

2.5.0 (eller tidigare stabil version)

@cacheable/memory

2.2.1

2.2.0 (eller tidigare stabil version)

@cacheable/node-cache

3.1.2

3.1.1 (eller tidigare stabil version)

@cacheable/net

2.1.1

2.1.0 (eller tidigare stabil version)

ecto

5.0.1

5.0.0 (eller tidigare stabil version)

Wormen spred sig därefter till paket inom organisationer som Ornikar (bland annat @ornikar/eslint-config-*, @ornikar/prettier-config, @ornikar/babel-preset-* och många fler), Qlik (@nebula.js/nucleus), HubSync (@hubsync/web-sdk-react) och många andra. En fullständig, kontinuerligt uppdaterad lista underhålls av Wiz Research i deras offentliga GitHub-repository.

Viktigt: npm-registret förändrades snabbt under hela incidenten. Kl. 17:40 IST den 4 augusti återställdes tidigare rena versioner som de senaste för minst nio kärnpaket, däribland keyv@5.6.0, flat-cache@6.1.23 och cache-manager@7.2.9. Organisationer måste verifiera exponeringen med hjälp av de exakta paketversionerna som anges i lockfilerna, inte de aktuella registertaggarna.

 

Analys av skadlig kod

Översikt över nyttolasten

Skadlig programvara distribueras i en tvåstegsarkitektur:

Steg 1 – setup.mjs (Dropper): Detta lätta Node.js-skript fungerar som den initiala nyttolasten. Det kontrollerar om Bun JavaScript-runtime finns och, om så inte är fallet, laddar det ner Bun v1.3.13 från de officiella GitHub-utgåvorna. Därefter överlämnar det exekveringen till huvudpaketet för informationsstöld innan den tillfälliga runtime-katalogen raderas för att minska de forensiska spåren.

Steg 2 – Math_Symbol.js / math_init.js (infostealer): Ett kraftigt förvrängt, kompilerat paket på 727 680 byte som körs via Bun-runtime-miljön. Detta är den centrala motorn för insamling av inloggningsuppgifter. Båda filnamnen (Math_Symbol.js och math_init.js) har observerats i det vilda och innehåller identisk funktionalitet med samma SHA-1-hash.

Mål för insamling av inloggningsuppgifter

Infostealern inventerar och exfiltrerar systematiskt:

  • Molninloggningsuppgifter: AWS-åtkomstnycklar, SSM Parameter Store-värden (med WithDecryption: true), AWS Secrets Manager-hemligheter, Azure- och GCP-inloggningsuppgifter
  • CI/CD-hemligheter: GitHub Actions-hemligheter, inklusive extrahering av ”isSecret”:true-värden från minnet hos en egenhostad runner, GitHub-workflow-tokens
  • Utvecklartoken: GitHub Personal Access Tokens (prefixen ghp_, gho_, ghs_), npm-publiceringstoken (prefixet npm_), varje token valideras i realtid mot registry.npmjs.org/-/whoami före exfiltrering
  • Infrastrukturhemligheter: Kubernetes-hemligheter från alla tillgängliga namnutrymmen, HashiCorp Vault-tokens och KV-hemligheter, Terraform-autentiseringsuppgifter, SSH-nycklar, databasanslutningssträngar
  • AI- och IDE-konfiguration: Claude API-konfigurationsfiler, inloggningsuppgifter för AI-relaterade tjänster
  • Kryptovalutaplånböcker: Lokala plånboksfiler och nycklar
  • Inloggningsuppgifter för tjänster: Stripe, Slack, Twilio och andra API-nycklar från tredjepartsleverantörer
  • Hela processmiljön: Alla miljövariabler från den komprometterade processen

Persistensmekanismer

Keyv-repositoriet behöll separata kopplingar till Claude Code (.claude/settings.json) och Visual Studio Code (.vscode/). Dessa persistensmekanismer på IDE-nivå kan köra nyttolasten så snart en användare litar på arbetsytan eller godkänner projektkonfigurationen, vilket ger en sekundär körväg oberoende av npm install-livscykelskript.

Skadlig programvara installerar även en bevakare för återkallande av autentiseringsuppgifter – en fälla som utlöser en lokal hanterare som tillhandahålls av angriparen när token byts ut. De som hanterar incidenten måste ta bort denna bevakare innan de byter ut några autentiseringsuppgifter.

Kommando och kontroll

Skadlig programvaran hämtar sina C2-domäner från ett smart kontrakt på Ethereum (StringListStore) med hjälp av ett eth_call istället för att bädda in dem i nyttolasten. Denna blockkedjebaserade C2-upplösning gör det möjligt för operatören att uppdatera infrastrukturen utan att behöva modifiera den skadliga programvaran. Historiken på blockkedjan visar att kontraktet ursprungligen konfigurerades med tre domäner innan det uppdaterades för att endast returnera npm-cache[.]com. Kontraktets ägare finansierades av en adress som tidigare flaggats för bedräglig verksamhet.

Exfiltrering

Stulna data krypteras med ett hybridsystem bestående av AES-256 och RSA-4096 och exfiltreras sedan via två kanaler:

  • Offentliga GitHub-repositorier som skapats under komprometterade identiteter, med beskrivningen ”Shai-Hulud: Here We Go Again”
  • Domänen npm-cache[.]com

De första commit-uppdateringarna till utläckningsrepositorierna innehåller hottexposten: ”IfYouBlockThisAPIKeyItWillCrashTheLiveProductionServersOfAllThirdPartyClients.”

 

Kända indikatorer på intrång (IoC)

Kategori

Indikator

Beskrivning

Domän

npm-cache[.]com

Primär C2- och dataexfiltreringsdomän; levereras via Cloudflare

Domän

registry[.]npmjs[.]org

Endpunkt för tokenvalidering som missbrukas för verifiering av inloggningsuppgifter i realtid före exfiltrering

Domän

eth-mainnet[.]nodereal[.]io

Ethereum RPC-ändpunkt som används för att hämta C2-domäner baserade på smarta kontrakt

Domän

go[.]getblock[.]io

Ethereum RPC-ändpunkt som används för hämtning av C2-domäner baserat på smarta kontrakt

Domän

eth[.]llamarpc[.]com

Ethereum RPC-ändpunkt som används för att hämta C2-domäner baserade på smarta kontrakt

Domän

pypi-get[.]com

Ytterligare infrastruktur som kontrolleras av angriparen

Domän

js-mirror[.]com

Ytterligare infrastruktur som kontrolleras av angriparen

IPv4

104[.]21[.]35[.]216

Cloudflare-IP kopplad till npm-cache[.]com

IPv4

172[.]67[.]167[.]200

Cloudflare-IP kopplad till eth[.]llamarpc[.]com

IPv4

185[.]44[.]207[.]215

IP kopplad till go[.]getblock[.]io ETH RPC

IPv4

35[.]175[.]164[.]77

AWS-IP kopplad till eth-mainnet[.]nodereal[.]io

Filnamn

Math_Symbol.js

Förvrängd infostealer-payload (727 680 byte); distribuerad via preinstall-skript i npm-paket

Filnamn

math_init.js

Variant av infostealer-payloaden med identisk funktionalitet

Filnamn

setup.mjs

Stage-1-dropper; hämtar Bun-runtime och utlöser körning av infostealer

Filhash (SHA-1)

35a672cf34b996b91f3e1c28cbf3a05a37e036e4

Math_Symbol.js / math_init.js – infostealer-nyttolast

Filhash (SHA-1)

686aa40d0fc22c8d569494543a0f891f359f2f99

setup.mjs i katalogen .claude (Claude Code hook)

Filhash (SHA-1)

f525d52ceb966516686b482d3dc0137028cc6a63

setup.mjs finns i katalogen .vscode (VS Code-hook)

Användaragent

Bun/1.3.13

HTTP-user-agent-sträng som används vid nedladdning av Bun-runtime och C2-kommunikation

Filsystemväg

/tmp/bun-dl-*/

Tillfällig katalog som används för nedladdning och mellanlagring av Bun-runtime

Filsystemets sökväg

node_modules/keyv/Math_Symbol.js

Platsen för infostealer-payloaden i det installerade paketträdet

Sträng

Shai-Hulud: Here We Go Again

Beskrivning av GitHub-repositoriet som används för exfiltreringsrepositorier

Sträng

Om du blockerar den här API-nyckeln kommer det att krascha live-produktionsservrarna hos alla tredjepartsklienter

Hotfull sträng i de första exfiltrerings-commitsen

 

 

Detekteringar och hotjakt

Säkerhetsteam bör implementera följande detekteringsåtgärder:

  • Beroendegranskning: Skanna alla package-lock.json-, yarn.lock-, pnpm-lock.yaml- och bun.lockb-filer för att hitta de drabbade paketen och versionerna. Lita inte på aktuella registertaggar – använd uteslutande de versioner som anges i låsfilerna.
  • Filsystemindikatorer: Sök igenom utvecklingsarbetsstationer, CI/CD-körare och byggservrar efter förekomsten av Math_Symbol.js, math_init.js och setup.mjs i node_modules-träd och tillfälliga kataloger som matchar /tmp/bun-dl-*/.
  • Nätverksövervakning: Skicka varningar vid utgående anslutningar och DNS-förfrågningar till npm-cache[.]com, pypi-get[.]com, js-mirror[.]com samt de Ethereum RPC-ändpunkter som anges i IOC:erna ovan. Övervaka efter användaragentsträngen Bun/1.3.13.
  • GitHub-granskning: Granska organisationer för oväntade offentliga repositorier med beskrivningen ”Shai-Hulud: Here We Go Again” eller commit som innehåller hotsträngen.
  • Övervakning av preinstall-skript: Granska package.json-filer i alla projekt för oväntade preinstall-skriptposter som refererar till setup.mjs.
  • Förtroende för IDE-arbetsytor: Kontrollera om det finns obehöriga .claude/settings.json- och .vscode/-konfigurationer som kan ladda externa nyttolaster.

 

Åtgärder och avhjälpande åtgärder

Omedelbara åtgärder

  • Identifiera och ta bort drabbade versioner: Granska alla miljöer och ta bort alla installationer av de skadliga paketversionerna. Uppgradera till rena, verifierade versioner.
  • Ta bort övervakaren för återkallande av autentiseringsuppgifter först: Rotera inte token innan du har tagit bort skadlig programvara. Den skadliga koden installerar en övervakare som aktiveras vid återkallande av token. Om du roterar autentiseringsuppgifter i förtid kan en hanterare som tillhandahålls av angriparen köras. Ta bort den skadliga programvaran från drabbade system innan du fortsätter med rotationen av autentiseringsuppgifter.
  • Utgå från att alla autentiseringsuppgifter har komprometterats: Om någon drabbad version har installerats ska alla autentiseringsuppgifter som är tillgängliga i den miljön behandlas som stulna. Detta inkluderar molnautentiseringsuppgifter, npm-token, GitHub PAT:er, SSH-nycklar, CI/CD-hemligheter, databasautentiseringsuppgifter och API-nycklar från tredje part.
  • Rotera alla exponerade inloggningsuppgifter: Efter att skadlig programvara har tagits bort ska följande roteras: alla npm-publiceringstoken, GitHub Personal Access Tokens och OAuth-token, AWS IAM-åtkomstnycklar, autentiseringsuppgifter för Azure- och GCP-tjänsteprinciper, Kubernetes-tjänstekontotoken, HashiCorp Vault-token, databaslösenord, SSH-nycklar och API-nycklar från tredjeparter (Stripe, Slack, Twilio osv.).
  • Återkalla och utfärda nya npm-/GitHub-token: Använd npm- och GitHub-administratörskonsolerna för att tvinga fram återkallandet av alla potentiellt exponerade token. Generera nya token med minsta möjliga behörighetsomfång.

Systemåterställning

  • Återuppbygg de drabbade systemen: Behandla alla utvecklingsarbetsstationer, CI/CD-körare eller byggservrar där ett skadligt paket har installerats som potentiellt komprometterade. Återuppbygg från en bild eller ögonblicksbild som bekräftats vara ren.
  • Rensa lokala cacher: Rensa npm-cachen (npm cache clean --force), Yarn-cachen, pnpm-lagret och Bun-cachen för att eliminera cachelagrade skadliga paket.
  • Ta bort och återskapa virtuella miljöer: Nöj dig inte med att bara nedgradera drabbade paket. Ta bort node_modules-katalogerna och återskapa de virtuella Python-miljöerna helt och hållet.

Granskning av moln- och källkodsmiljöer

  • Granska molnmiljöer: Granska AWS CloudTrail, Azure Activity Logs och GCP Audit Logs för obehöriga API-anrop som härrör från tidsperioden då paketet installerades. Kontrollera om det skett oväntad skapande av IAM-användare eller -roller, åtkomst till SSM Parameter Store med dekryptering samt åtkomst till Secrets Manager.
  • Granska GitHub-granskningsloggar: Undersök organisationens granskningsloggar för oväntad skapande av repositorier, generering av token och ändringar i arbetsflöden.
  • Sök efter repositorier för dataexfiltrering: Sök efter offentliga repositorier som skapats under din organisations identiteter med beskrivningen ”Shai-Hulud: Here We Go Again”.

Säkring av leveranskedjan

  • Fäst beroenden: Använd exakt versionsfästning i alla package.json-filer och lägg in låsfiler i versionshanteringen.
  • Uppgradera till npm 12: npm 12 blockerar som standard icke-godkända livscykelskript för beroenden, vilket förhindrar automatisk körning av preinstall-skript. Tidigare npm-klienter förblir sårbara.
  • Tillämpa SLSA och OIDC: Kräv SLSA-härkomstintyg och verifiera dem vid byggtillfället. Observera dock att denna kampanj visade att härkomst i sig inte är tillräckligt när angriparen kontrollerar byggpipeline – härkomst måste kombineras med identitetsverifiering.
  • Aktivera tillåtna listor för beroenden: Begränsa tillåtna paketkällor och versioner genom verktyg som Socket, Semgrep Supply Chain eller policyerna i ditt artefaktregister.
  • Implementera verifiering av paketintegritet: Använd npm-auditsignaturer och verifiera registrets integritetshashar där detta stöds.
  • Aktivera MFA på alla underhållarkonton: Kräv hårdvarubaserad MFA för alla npm- och GitHub-konton med publiceringsbehörighet.
  • Blockera skadliga domäner: Lägg till de IOC:er som anges ovan i dina blockeringslistor för nätverksgränsen och dina DNS-filtreringslösningar.

Om du är orolig för någon av de hot som beskrivs i detta meddelande eller behöver hjälp med att avgöra vilka åtgärder du bör vidta för att skydda dig mot de mest väsentliga hoten som din organisation står inför, vänligen kontakta din kundansvarige eller hör av dig till oss för att ta reda på hur du kan skydda din organisation.