V júni 2026 výskumníci odhalili ďalšiu evolúciu rodiny malvéru Mini Shai-Hulud, ktorá dostala názov Miasma. Na rozdiel od tradičného npm malvéru, ktorý sa zameriava na hŕstku balíkov, táto kampaň ukázala, ako sa kompromitácia jediného prvku vývojárskej infraštruktúry dokáže rýchlo rozšíriť naprieč viacerými ekosystémami: npm, GitHub Actions a dokonca aj Go modulmi.
Útočníci sa nezamerali na koncových používateľov. Zamerali sa na vydavateľov balíkov, CI/CD pipeline a mechanizmy dôvery, ktoré umožňujú softvéru putovať z notebooku vývojára do produkcie bez toho, aby ho niekto po ceste znovu skontroloval. Pre nič z toho neexistuje žiadne CVE, pretože na dotknutom kóde nikdy nebolo nič chybné. Vstupným bodom bol ukradnutý prístupový údaj, nie zraniteľnosť.
Jednu vec treba zdôrazniť hneď na úvod: 12. mája 2026 skupina TeamPCP, ktorá za touto rodinou červov pôvodne stála, verejne zverejnila kompletný zdrojový kód Shai-Hulud/Mini Shai-Hulud na GitHube pod licenciou MIT. To mení spôsob, akým treba tento príbeh čítať. Štyri vlny, ktoré nasledovali, zdieľajú rovnakú sadu nástrojov a rovnaké techniky, no zdieľané nástroje už neznamenajú zdieľaného operátora. Keď je framework verejný, kampaň vyzerajúcu na nerozoznanie od tej, ktorú vedie samotný TeamPCP, môže spustiť ktorýkoľvek technicky zdatný aktér. Nasledujúci text preto treba čítať ako popis prekrývajúcich sa taktík, techník a postupov (TTP), nie ako potvrdenú atribúciu jedinej skupine.
Dotknuté balíky (npm a Go)
| Balík | Kompromitovaná verzia |
|---|---|
hexo-deployer-wrangler | 1.0.4 |
hexo-shoka-swiper | 0.1.10 |
leo-auth | 4.0.6 |
leo-aws | 2.0.4 |
leo-cache | 1.0.2 |
leo-cdk-lib | 0.0.2 |
leo-cli | 3.0.3 |
leo-config | 1.1.1 |
leo-connector-elasticsearch | 2.0.6 |
leo-connector-mongo | 3.0.8 |
leo-connector-mysql | 3.0.3 |
leo-connector-oracle | 2.0.1 |
leo-connector-redshift | 3.0.6 |
leo-cron | 2.0.2 |
leo-logger | 1.0.8 |
leo-sdk | 6.0.19 |
leo-streams | 2.0.1 |
prism-silq | 1.0.1 |
rstreams-metrics | 2.0.2 |
rstreams-shard-util | 1.0.1 |
serverless-convention | 2.0.4 |
serverless-leo | 3.0.14 |
solo-nav | 1.0.1 |
github.com/verana-labs/verana-blockchain (Go) | v0.10.1-dev.20 |
Socket vo vyšetrovaní pokračuje; nové zistenia priebežne dopĺňa na svoju stránku sledujúcu kampaň Miasma.
Ak váš strom závislostí obsahuje ktorýkoľvek z týchto balíkov v uvedených verziách (alebo balíky zo skorších kompromitovaných vĺn tej istej kampane zo začiatku júna), považujte prostredie za potenciálne kompromitované a postupujte podľa okamžitých nápravných krokov uvedených nižšie.
Časová os
24. júna 2026
↓
Kompromitovaný účet správcu LeoPlatform
↓
Publikovaných 23 škodlivých verzií balíkov (v rozstupe sekúnd)
↓
Payload v binding.gyp sa spúšťa pri inštalácii
↓
Ukradnuté prístupové údaje vývojárov a CI/CD
↓
Nasadený GitHub Actions workflow („Run Copilot“)
↓
Ukradnuté tajomstvá exfiltrované do verejných GitHub repozitárov
↓
Go modul (Verana Blockchain) kompromitovaný príbuznou technikou
↓
Výskumníci zo Socket, Wiz, Sonatype a ďalších kampaň identifikujú a zverejňujú
Ide o štvrtú vlnu tej istej rodiny kampaní za necelý mesiac: prvýkrát sa objavila 1. júna proti npm namespace spoločnosti Red Hat, potom prišla vlna 57 balíkov 3. júna a napokon táto vlna LeoPlatform/Go 24. až 25. júna. Ako sme uviedli vyššie, TeamPCP zverejnil zdrojový kód základného frameworku červa 12. mája, takže „tá istá rodina kampaní“ vyjadruje zdieľané TTP naprieč týmito vlnami, nie potvrdený dôkaz o jedinom operátorovi stojacom za všetkými štyrmi.
Čo sa v skutočnosti stalo
- Správcovi npm ekosystému LeoPlatform boli ukradnuté prihlasovacie údaje k účtu alebo npm token, s najväčšou pravdepodobnosťou infostealerom.
- Útočník využil tento ukradnutý prístup na publikovanie trojanizovaných verzií balíkov, ktoré správca už legitímne vlastnil. Nič nebolo treba „hacknuť“ v tradičnom zmysle slova, pretože útočník už mal dôveryhodnú identitu vydavateľa.
- Každý, kto si nainštaloval jednu z týchto verzií, spustil skrytý payload, ktorý mu ukradol jeho vlastné prístupové údaje.
- Niektoré z ukradnutých údajov patrili prostrediam GitHub Actions, čo útočníkovi umožnilo podstrčiť škodlivý workflow a vyťahovať CI/CD tajomstvá priamo z runnera.
- Nezávisle od toho bol kompromitovaný aj Go modul, a to príbuznou, ale odlišnou technikou, čo ukazuje, že kampaň nie je viazaná na žiaden konkrétny jazyk ani správcu balíkov.
- Celá vec bola odhalená preto, že viaceré nezávislé bezpečnostné výskumné tímy presne tento vzor sledovali už od skorších vĺn tej istej kampane.
Technický rozbor
Fáza 1: Kompromitovaný správca
Npm účet czirker, spojený s LeoPlatform, bol kompromitovaný, s najväčšou pravdepodobnosťou cez uniknuté prihlasovacie údaje alebo token vytiahnutý infostealerom, ktorý už bežal na počítači správcu.
Fáza 2: Publikovanie škodlivých balíkov
Pomocou ukradnutého tokenu útočník publikoval 23 škodlivých verzií balíkov naprieč ekosystémami LeoPlatform a RStreams v šesťsekundovom okne. Takáto rýchlosť ukazuje na skriptovaný, automatizovaný publikačný nástroj, nie na človeka, ktorý súbory nahráva ručne.
Najkonkrétnejší detail celej kampane sa skrýva práve v tejto fáze: útočník nielenže publikoval škodlivé verzie, ale zároveň presmeroval dist-tag latest balíka leo-sdk na otrávenú verziu 6.0.19, zatiaľ čo čisté vydanie 7.1.21 zostalo dostupné len pod menej nápadným tagom awsv3. V praxi to znamená, že každé prostredie, ktoré spustilo npm install leo-sdk bez explicitného semver pinu, bolo aktívne nasmerované na červa, hoci čisté vydanie celý čas existovalo. Praktické ponaučenie je neúprosné: pinovanie verzie, nie tagu, bolo skutočným rozdielom medzi čistou inštaláciou a kompromitáciou.
Fáza 3: Spustenie pri inštalácii
Toto je tá šikovná časť. Väčšina škodlivých npm balíkov sa odhalí preto, že skenery sledujú polia skriptov preinstall a postinstall v súbore package.json. Miasma ich úplne obchádza a namiesto toho pridáva súbor binding.gyp, teda konfiguráciu, ktorú Node.js používa na kompiláciu natívnych modulov počas inštalácie. Keďže binding.gyp je úplne bežnou súčasťou zostavovania natívnych doplnkov, spúšťa kód počas npm install bez toho, aby sa čo i len dotkol polí, ktoré väčšina nástrojov sleduje.
Táto technika mala dve skutočné mitigácie a stojí za to byť pri oboch presný. Prvá už existovala: npm install --ignore-scripts podľa vlastnej dokumentácie npm skutočne potláča implicitný hook node-gyp rebuild, ktorý súbor binding.gyp spúšťa. Samo o sebe to nie je úplná obrana, pretože škodlivý balík sa stále stiahne a rozbalí a neskorší rebuild bez tohto prepínača ho stále môže spustiť, ale túto konkrétnu cestu vykonania blokuje. Druhá mitigácia prišla o tri týždne neskoro: npm v12, ktorý vyšiel v júli 2026, tento vektor v predvolenom nastavení uzatvára a s implicitným node-gyp rebuild spusteným cez binding.gyp zaobchádza presne ako s akýmkoľvek iným inštalačným skriptom, teda ho blokuje, pokiaľ balík nie je výslovne na zozname povolených. Technika „Phantom Gyp“ kampane Miasma bola v podstate priamym zneužitím presne tej medzery, na ktorej uzavretie bol npm v12 postavený.
Fáza 4: Zber tajomstiev
Po spustení payload zbiera širokú škálu prístupových údajov, okrem iného:
- npm a PyPI tokeny
- GitHub Personal Access Tokeny a GitHub OIDC tokeny
- prístupové údaje k AWS, Azure a GCP
- SSH kľúče
- konfiguračné súbory a cesty k prístupovým údajom pre Claude Code, Cursor a ďalších AI asistentov pre programovanie
- OpenAI API kľúče
- Slack a Twilio tokeny, Docker auth súbory, Kubernetes konfigurácie, dáta z Vaultu a históriu shellu
Fáza 5: Zneužitie GitHubu
Malvér podstrčí GitHub Actions workflow (pozorovaný pod názvom „Run Copilot“), ktorý počas behu vyťahuje tajomstvá priamo z pamäte CI runnera. Ukradnuté dáta sú zašifrované a odoslané do novovytvorených verejných GitHub repozitárov, ktoré slúžia ako mŕtve schránky; v čase písania tohto článku nesie exfiltračnú značku kampane vyše 550 repozitárov. Pri súvisiacom incidente z toho istého dňa útočník cez force-push vložil škodlivý commit do široko používanej GitHub Action a presmeroval na neho verzijné tagy, čo znamená, že každý workflow, ktorý sa od toho momentu spustil proti týmto tagom, vykonal payload útočníka priamo vnútri GitHub Actions runnera.
Fáza 6: Šírenie
Kompromitovaný počítač vývojára
↓
Ukradnuté GitHub prístupové údaje vývojára
↓
Tajomstvá CI/CD pipeline vyťažené z runnera
↓
Ukradnutý npm token použitý na publikovanie ďalších škodlivých balíkov
↓
Ďalší vývojári si inštalujú kompromitované balíky
↓
(opakuje sa)
Každá úspešná kompromitácia sa stáva odrazovým mostíkom pre ďalšiu. Práve to robí z tejto kampane samošíriacu sa kampaň, nie jednorazový incident.
Prečo je tento útok iný
| Staré supply chain útoky | Miasma |
|---|---|
| Jeden balík | Celý ekosystém |
| Krádež kryptomien | Plošná krádež prístupových údajov |
| Jeden jazyk | Viacero jazykov (npm, teraz aj Go) |
| Jeden správca | Vývojárska infraštruktúra ako celok |
| Statický malvér | Samošíriaci sa, medzi vlnami sa vyvíja |
Skoršie npm supply chain incidenty boli väčšinou v štýle „rýchlo ukradni a zmizni“: kompromitovať balík, ukradnúť kľúče k peňaženkám alebo session tokeny a ísť ďalej. Miasma sa správa skôr ako červ s obchodným modelom. Každú úspešnú infekciu považuje za palivo pre ďalšiu vlnu a preukázateľne sa stále vyvíja, a to aj po viac než troch týždňoch a štyroch samostatných vlnách.
Prečo sa cieľom stal GitHub Actions
GitHub Actions sedí na mimoriadne cennom mieste softvérového dodávateľského reťazca: drží OIDC tokeny používané na dôveryhodné publikovanie bez prístupových údajov k cloudovým poskytovateľom a registrom, ukladá dlhodobé CI tajomstvá a už z princípu beží automatizovane a bez dozoru. Kompromitácia CI runnera neodhaľuje len notebook jedného vývojára, odhaľuje každú deployment pipeline, každé publikovanie do registra a každý cloudový prístupový údaj, ktorého sa daný workflow dotkne. To je oveľa väčší dosah než lokálne prostredie ktoréhokoľvek jednotlivého vývojára, a práve preto kampaň vytvorila špecializované nástroje zamerané cielene na neho.
Prečo je rozšírenie na Go dôležité
Väčšina správ o tejto kampani sa sústredila na npm, pretože práve tam sa nachádza väčšina balíkov. Kompromitácia Go modulu je však pravdepodobne najdôležitejším detailom celého príbehu a zároveň tým, ktorý väčšina článkov preskočí.
Go vzorka nepoužíva binding.gyp. Nespolieha sa vôbec na mechanizmy rozlišovania modulov ani na build mechanizmy jazyka Go. Namiesto toho môže vývojár, ktorý si repozitár jednoducho naklonuje alebo ho otvorí v dôveryhodnom IDE či AI asistentovi pre programovanie, spustiť payload len cez konfiguráciu projektu.
To hovorí niečo dôležité: útočníkov v zásade nezaujíma JavaScript, npm ani mechanika žiadneho konkrétneho správcu balíkov. Zaujímajú ich vývojári, kdekoľvek vývojári vkladajú dôveru do automatizovaných nástrojov, či je to inštalačný skript, build krok alebo IDE otvárajúce priečinok. Na jazyku nezáleží. Na prístupových údajoch vývojárov áno.
Väčšie ponaučenie
Staré uvažovanie:
Skenujeme závislosti
↓
Opravujeme známe CVE
↓
Sme v bezpečí
Súčasná realita:
Vývojár je kompromitovaný
↓
CI/CD je kompromitované
↓
Legitímny balík je publikovaný so škodlivým kódom
↓
Každý odberateľ nižšie v reťazci si ho nainštaluje
↓
V žiadnom kroku nie je potrebné žiadne CVE
Skenovanie závislostí odpovedá na otázku „má tento kód známu chybu“. Miasma odhaľuje úplne inú otázku, na ktorú väčšina bezpečnostných programov nie je vôbec pripravená odpovedať: „dôverujem ľuďom a automatizovaným systémom, ktoré smú publikovať kód do môjho prostredia, práve teraz, dnes“.
Príležitosti na detekciu
Namiesto otázky „ako to zastaviť“ je užitočnejšie pýtať sa, kde mal obranca reálnu šancu všimnúť si, že niečo nie je v poriadku. Práve tu väčšina správ o kampani Miasma končí, takže stojí za to prejsť si to podrobnejšie.
Rýchlosť publikovania. 23 verzií balíkov publikovaných v šesťsekundovom okne nie je niečo, čo robí človek. Každá organizácia, ktorá prevádzkuje vlastné zrkadlo npm registra alebo sleduje udalosti verejného registra pre balíky, na ktorých závisí, by takéto publikačné dávky dokázala automaticky označiť. Jedno zvýšenie verzie je normálne. Dve desiatky za pár sekúnd sú signálom samy o sebe, nezávisle od toho, čo balík v skutočnosti obsahuje.
Zmeny dist-tagov bez zvýšenia verzie, o ktoré používatelia žiadali. Únos leo-sdk fungoval práve preto, že latest sa presunul na nižšie, staršie vyzerajúce číslo verzie (6.0.19), zatiaľ čo novšie čisté vydanie (7.1.21) sedelo pod iným tagom. Akýkoľvek nástroj, ktorý porovnáva dist-tagy balíka v čase, nie len jeho zoznam verzií, by zachytil, že latest ukazuje v postupnosti verzií späť, čo takmer nikdy nie je legitímne správanie.
Build artefakty, ktoré nezodpovedajú zdrojovému kódu. Kompromitovaný balík leo-sdk narástol z 10 KB súboru index.js v čistej verzii na 5 MB index.js v otrávenej verzii, so súborom binding.gyp, ktorý v skutočnom GitHub repozitári projektu nikde neexistuje. Porovnanie toho, čo je publikované v registri, s tým, čo je commitnuté v správe zdrojového kódu, balík po balíku, by to okamžite odhalilo. Väčšina organizácií toto porovnanie nikdy nerobí.
Neočakávané natívne buildy pri čisto JavaScriptových balíkoch. leo-sdk je JavaScriptové SDK bez akejkoľvek legitímnej potreby natívnej kompilácie. Súbor binding.gyp, ktorý sa objaví v balíku, ktorý ho nikdy predtým neobsahoval alebo nemá žiaden rozumný dôvod ho potrebovať, je silným signálom anomálie sám o sebe, dávno predtým, než niekto preskúma, čo súbor v skutočnosti robí.
Nové workflow súbory, ktoré sa objavia bez zodpovedajúceho pull requestu. Workflow súbor s názvom „Run Copilot“, ktorý sa objaví v .github/workflows/ bez prepojeného PR, bez review a bez autora, ktorého by niekto poznal, je presne ten typ zmeny, na ktorej zachytenie existuje ochrana vetiev a povinné review, pokiaľ sa skutočne vynucujú aj konkrétne na workflow súboroch.
Odchádzajúca komunikácia do čerstvo vytvorených GitHub repozitárov. Keďže exfiltrácia sa spoliehala na novovytvorené verejné repozitáre slúžiace ako mŕtve schránky, CI runnery alebo počítače vývojárov, ktoré volajú API na vytvorenie nových repozitárov alebo pushujú do repozitárov, ktoré pred hodinou neexistovali, predstavujú detegovateľný a pomerne nezvyčajný vzor správania.
Použitie OIDC a tokenov mimo bežného vzoru. GitHub OIDC token alebo npm publikačný token použitý z IP rozsahu, workflow alebo časového okna, z ktorého nikdy predtým použitý nebol, je klasickým signálom anomálie identity, a to takým, na ktorého zachytenie netreba vedieť nič o tejto konkrétnej kampani.
Nič z toho nevyžaduje databázu CVE ani predchádzajúcu znalosť konkrétne kampane Miasma. Vyžaduje to skutočne sledovať, ako sa dôvera, publikačné správanie a identity vo vašom prostredí v čase pohybujú, nie len to, čo je v jednom okamihu uvedené v manifeste.
Čo by mali organizácie urobiť
Okamžite
- Rotujte prístupové údaje pre každé prostredie, ktoré si nainštalovalo dotknutý balík, ale až po odstránení škodlivej verzie a potvrdení, že je odstránená aj perzistencia, nie skôr.
- Aktualizujte alebo odstráňte dotknuté verzie balíkov naprieč lockfile súbormi, cache, kontajnermi a CI runnermi, nie len v manifeste najvyššej úrovne.
- Zrušte a znovu vydajte všetky GitHub tokeny, OIDC konfigurácie alebo npm tokeny, ktoré mohli byť vystavené.
- Pinujte GitHub Actions podľa hashu commitu namiesto meniteľných verzijných tagov.
Strednodobo
- Zaveďte zoznamy povolených balíkov pre to, čo je prípustné v CI/CD a produkčných buildoch.
- Vyžadujte provenance balíkov a podpisovanie tam, kde sú dostupné.
- Udržiavajte skutočný Software Bill of Materials (SBOM), nie snímku z jedného okamihu.
- Pridajte ochrannú lehotu, kým sa novo publikované verzie balíkov začnú v builde považovať za dôveryhodné.
Dlhodobo
- Priebežná validácia toho, čo vo vašom prostredí skutočne beží, nie periodické audity.
- Monitorovanie repozitárov a CI/CD pre neočakávané zmeny workflow alebo publikačného správania.
- Priebežná analýza útočných ciest: nie len „je tento balík zraniteľný“, ale „kam by sa niekto dostal, keby bol tento balík škodlivý“.
- Monitorovanie identít vývojárov, pretože v tejto kampani bola skutočnou útočnou plochou práve identita.
Prečo je to dôležité pre Penetrify
Miasma nebola npm problém. Bol to problém identity. Problém CI/CD. Problém dôvery. Problém útočnej cesty.
Útočníci neobjavili zraniteľnosť. Objavili cestu od pracovnej stanice jediného vývojára k tisícom systémov nižšie v reťazci, a táto cesta existovala výlučne vo vzťahoch, ktoré väčšina bezpečnostných programov v skutočnosti nikdy nemonitoruje: ktorí ľudia môžu publikovať kód, ktoré tokeny môžu spustiť nasadenie, ktoré workflow bežia bez dozoru so skutočným prístupom do produkcie.
npm v12 uzatvára konkrétny vektor vykonania, na ktorý sa Miasma spoliehala. S problémom identity, ktorý leží pod ním, nerobí nič. Ako to v správach o nasadení npm v12 vyjadril Moshe Siman Tov Bustan z OX Security: keď útočník ovláda prihlasovacie údaje legitímneho správcu, blokovanie inštalačných skriptov nepomôže, pretože škodlivý kód sa šíri ako dôveryhodné, podpísané vydanie.
To je celý argument, ktorý tento článok predkladá, vyjadrený jednoduchšie, než by sme to dokázali my. Moderná bezpečnosť softvérového dodávateľského reťazca sa musí posunúť za hranice skenovania závislostí smerom k priebežnému porozumeniu toho, ako sa vzťahy dôvery vyvíjajú naprieč repozitármi, build pipeline, identitami a produkčnými prostrediami, nie len k tomu, aké CVE sa nachádzajú v manifeste.
Zdroje
- The Hacker News: Miasma Malware Targets npm Packages and GitHub Actions in Supply Chain Attack
- Socket: Miasma Mini Shai-Hulud Hits LeoPlatform npm Packages and Go Ecosystem
- StepSecurity: Mass npm Supply Chain Attack: 20 Leo Platform Packages Compromised a Supply Chain Compromise: codfish/semantic-release-action
- Endor Labs: Shai-Hulud Strikes Leo Platform npm
- Corgea: Leo Platform npm packages compromised with Phantom Gyp Miasma toolkit
- Snyk: Node-gyp Supply Chain Compromise
- Datadog Security Labs: Shai-Hulud Goes Open Source
- The Register: Malware crew TeamPCP open-sources its Shai-Hulud worm on GitHub
- GitHub Changelog: Upcoming breaking changes for npm v12
- TechTimes: npm v12 Ships This Month, Blocking Install Scripts That Enabled Year of Supply Chain Attacks
