Mini Shai-Hulud zasáhl openapi-react-query-codegen: 10 škodlivých verzí, npm provenance a proč samotný TanStack Query kompromitován nebyl Skip to content

Mini Shai-Hulud zasáhl openapi-react-query-codegen: 10 škodlivých verzí, npm provenance a proč samotný TanStack Query kompromitován nebyl

Ověřená analýza útoku z 28. srpna 2026 na @7nohe/openapi-react-query-codegen: 10 škodlivých verzí, GitHub Actions issue_comment, npm Trusted Publishing, platná provenance, binding.gyp, IOC, náprava a rozdíl oproti TanStack Query.

Publikováno Autor Čas čtení 17 min čtení

Ověřená analýza útoku z 28. srpna 2026 na @7nohe/openapi-react-query-codegen: 10 škodlivých verzí, GitHub Actions issue_comment, npm Trusted Publishing, platná provenance, binding.gyp, IOC, náprava a rozdíl oproti TanStack Query.

Na této stránce
  1. 1TL;DR
  2. 2Co se stalo 28. srpna?
  3. 3TanStack Query samotný nebyl napaden
  4. 4Co openapi-react-query-codegen dělá?
  5. 5Jak rozšířený byl balíček?
  6. 6Útok začal v GitHub Actions
  7. 7Jeden komentář mohl otevřít release path
  8. 8Checkout forku změnil input na code execution
  9. 9id-token: write umožnil Trusted Publishing
  10. 10Nebylo nutné ukrást heslo ani token
  11. 11Škodlivé release měly platnou provenance
  12. 12Provenance není malware scanner
  13. 13První execution path: binding.gyp
  14. 14Druhá cesta: preinstall
  15. 15Dva prerelease byly odlišné
  16. 16Hlavní payload: 3FWCvzduYZg.js
  17. 17Co payload dělal za běhu?
  18. 18Které credentials považovat za ohrožené?
  19. 19Proč je dev dependency nebezpečná
  20. 20Package install je code-execution surface
  21. 21Je jisté, že šlo o TeamPCP?
  22. 22Proč se Mini Shai-Hulud vrací?
  23. 23Květnový útok na TanStack byl technicky jiný
  24. 24Query byl čistý i v květnu
  25. 25Květnový incident měl skutečný downstream dopad
  26. 26Srpen vs květen
  27. 27Jak zjistit, zda projekt byl zasažen?
  28. 28Důležité IOC
  29. 29Co dělat po zasažené instalaci?
  30. 30Které verze jsou bezpečné?
  31. 31Co upstream opravil?
  32. 32Jak hardenovat GitHub Actions
  33. 33Jak hardenovat instalaci dependencies
  34. 34Produkční checklist
  35. 35Verdikt POLPROG

Dne 28. srpna 2026 byl kompromitován npm balíček @7nohe/openapi-react-query-codegen, nástroj generující TypeScript klienty a hooky pro TanStack Query z OpenAPI schémat.[1][2][3]

Útočník nepotřeboval npm heslo maintainera ani ukradený dlouhodobý publish token.

Cesta vedla přes release workflow v GitHub Actions.

Repozitář reagoval na:

issue_comment

a komentář v pull requestu s přesným textem:

npm publish

mohl spustit release flow bez dostatečného ověření, zda komentující je maintainer, collaborator nebo úplně externí uživatel GitHubu.[1][2]

Workflow potom:

checkoutoval kód z PR
→ spustil pnpm install
→ měl id-token: write
→ publikoval přes npm Trusted Publishing

[1][2]

Výsledkem bylo 10 škodlivých verzí publikovaných s platnou npm provenance.[1][3]

Hlavní ponaučení:

Provenance může správně potvrdit původ buildu, i když je samotný build škodlivý.

Je nutná i důležitá korekce: @tanstack/react-query samotný nebyl v tomto incidentu kompromitován. Napaden byl nezávislý code generator používaný s TanStack Query.[6][7]

Stav informací: 31. srpna 2026.

TL;DR

OtázkaOvěřená odpověď
Napadený balíček@7nohe/openapi-react-query-codegen
Datum28. srpna 2026
Škodlivých verzí10
Stabilních škodlivých verzí8
Škodlivých prerelease2
@tanstack/react-query kompromitován?Ne
Hlavní vektorChybně navržený GitHub Actions issue_comment release workflow
Potřebné heslo maintainera?Ne
Potřebný long-lived npm token?Ne
Publish oprávněníid-token: write + npm Trusted Publishing
Platná provenance?Ano
Provenance = bezpečný kód?Ne
Execution pathsbinding.gyp, u části verzí také preinstall
Hlavní payload3FWCvzduYZg.js
Aktuální latest3.0.2
SeverityCritical, CVSS 9.6
CVEK 31. srpnu advisory neuvádí známé CVE
RodinaAktivita spojovaná s Mini Shai-Hulud / jeho deriváty
Jistá atribuce operátora?Ne
Prioritní reakceIzolovat host a z čistého stroje rotovat všechny dostupné credentials

Co se stalo 28. srpna?

GitHub Security Advisory GHSA-9pvf-vcx3-x239 uvádí 10 škodlivých verzí publikovaných přibližně mezi 20:00 a 20:21 UTC.[1]

Osm stabilních verzí:

0.5.4
0.5.5
1.6.3
1.6.4
2.2.1
2.2.2
3.0.3
3.0.4

a dva prerelease:

0.0.0-365d4eb738d3146583431948d3ba6e27a32556be
0.0.0-ec7876d6c917dad516ba69bbfafc948b834bf0ab

[1][2]

Tag latest ukazoval na škodlivé 3.0.4 zhruba od 20:19:29 UTC do přibližně 22:51 UTC, kdy byl vrácen na čisté 3.0.2.[1]

TanStack Query samotný nebyl napaden

Titulek:

TanStack Query hacked

je nepřesný.

@7nohe/openapi-react-query-codegen je nezávislý projekt, který generuje kód pro:

@tanstack/react-query

[6]

Jde o technologické propojení, ne o oficiální TanStack balíček.

Oficiální npm stránka @tanstack/react-query je samostatná a TanStack ve svém květnovém postmortemu rovněž výslovně uvedl Query mezi nepostiženými rodinami.[7][11]

Co openapi-react-query-codegen dělá?

Generuje například:

  • typed API clients,
  • query keys,
  • queryOptions,
  • infiniteQueryOptions,
  • useQuery,
  • useMutation,
  • suspense helpery,
  • prefetch a SSR helpery.

[6]

Typický tok:

OpenAPI schema
      ↓
openapi-react-query-codegen
      ↓
TypeScript client
      ↓
TanStack Query hooks/options

Jde typicky o dev dependency, což z pohledu install-time malware neznamená nižší riziko.

Jak rozšířený byl balíček?

K 31. srpnu npm ukazoval přibližně 155 tisíc stažení týdně.[6]

Jde o dynamickou metriku.

Podstatnější je, že codegen běží na vývojářských strojích a CI runnerech, často v prostředí s GitHub, SSH, cloud a deployment credentials.

Útok začal v GitHub Actions

Release workflow naslouchal:

on:
  issue_comment:
    types: [created]

[1]

Samotný issue_comment není zranitelnost.

Nebezpečná byla kombinace:

externí komentář
+
žádná autorizace autora
+
checkout PR kódu
+
spuštění kódu
+
id-token: write
+
publish

Jeden komentář mohl otevřít release path

Workflow v zásadě ověřoval, zda komentář patřil k pull requestu a jeho obsah byl přesně npm publish.[1][2]

Chyběl spolehlivý authorization gate pro role jako:

OWNER
MEMBER
COLLABORATOR

Externí účet mohl otevřít fork PR a komentářem dosáhnout na privilegovaný job.

Checkout forku změnil input na code execution

Po checkoutu PR kódu workflow spustil:

pnpm install

[2]

Attacker-controlled obsah tak byl vykonán v release jobu s vysokými právy.

GitHub dlouhodobě doporučuje nespouštět nedůvěryhodný PR kód v privilegovaných workflows.[9]

id-token: write umožnil Trusted Publishing

Job měl:

permissions:
  id-token: write

[1][2]

To je legitimní permission pro npm Trusted Publishing přes OIDC.[10]

Problém nebyl OIDC samotný.

Problém byl, že útočníkův kód běžel v jobu oprávněném získat důvěryhodnou workload identity.

Nebylo nutné ukrást heslo ani token

StepSecurity zdůrazňuje, že útočník nepotřeboval maintainerovo npm heslo ani dlouhodobý publish token.[2]

Starý threat model:

ukrást token
→ publish

Nový model:

ovlivnit trusted workflow
→ workflow získá platnou identity
→ publish

Bezpečnostní hranice se tak přesouvá z účtu do CI/CD architektury.

Škodlivé release měly platnou provenance

Publikace proběhly přes skutečný workflow a Trusted Publishing, proto měly platné provenance attestations.[1][3]

Provenance správně potvrzovala:

tento artifact pochází
z tohoto repository
přes tento workflow

Neřešila však, zda kód checkoutovaný z PR byl legitimní.

Provenance není malware scanner

Provenance může potvrdit:

  • původ buildu,
  • identitu workflow,
  • vazbu na source,
  • chain of custody.

Automaticky nepotvrzuje:

  • bezpečný source code,
  • autorizovaný PR,
  • bezpečnou workflow logiku,
  • absenci malware.

Proto:

valid provenance
≠
safe package

npm Trusted Publishing používá OIDC k autentizaci workloadu a provenance k doložení původu, nikoli jako univerzální malware verdict.[10]

První execution path: binding.gyp

Některé stabilní škodlivé verze neměly viditelný:

"preinstall": "..."

[1]

Místo toho přidaly:

binding.gyp

GYP/Python evaluace byla zneužita tak, aby nakonec spustila JavaScript payload přes systémový příkaz.[1][5]

Security scanner, který kontroluje jen lifecycle scripts v package.json, by tuto cestu mohl minout.

Druhá cesta: preinstall

Další stabilní release přidaly:

"preinstall": "node 3FWCvzduYZg.js"

[1][2]

Konkrétně:

0.5.5
1.6.4
2.2.2
3.0.4

Předchozí stabilní verze:

0.5.4
1.6.3
2.2.1
3.0.3

používaly binding.gyp bez explicitního lifecycle scriptu.[1]

Dva prerelease byly odlišné

Dva 0.0.0-* prerelease obsahovaly škodlivý preinstall, ale kvůli:

"files": ["dist"]

nebyly odkazované payload files v tarballu.[1]

Všech 10 publikací je klasifikováno jako škodlivých, ale nejde o identické artefakty se stejnou execution path.

Hlavní payload: 3FWCvzduYZg.js

Stabilní škodlivé tarbally obsahovaly:

3FWCvzduYZg.js

o velikosti zhruba 4,4 až 6,4 MB podle verze.[1]

StepSecurity ukázal, že 0.5.4 narostla z přibližně 41 KB u 0.5.3 na více než 5,6 MB.[2]

Náhlá změna velikosti balíčku je užitečný supply-chain anomaly signal.

Co payload dělal za běhu?

StepSecurity detonoval postižené verze v izolovaných GitHub-hosted runnerech.[2]

Pozorované chování zahrnovalo:

Node spustí payload
→ curl stáhne Bun
→ Bun běží z /tmp/trinnyyyy-*
→ volá se gh auth token
→ dotazuje se Git Credential Manager
→ kontroluje ssh / scp
→ enumerují se procesy
→ spouští se dočasný updater.py

Pozorován byl také přístup k GitHub API a probing Google Cloud metadata hostname.[2]

Jde o malware zaměřený na credentials.

Které credentials považovat za ohrožené?

Skutečný rozsah závisí na oprávněních procesu.

Pokud se škodlivá verze spustila, za potenciálně exponované považujte vše, co proces mohl číst:

GitHub
npm
SSH
cloud
CI/CD
deployment
source repositories

Neznamená to, že každý secret byl na každém stroji skutečně exfiltrován.

Proč je dev dependency nebezpečná

Argument:

je to jen codegen
do browser bundle se nedostane

neřeší install-time malware.

Payload stačí spustit během:

npm install
pnpm install
yarn install

Developer a CI prostředí často mají nejcitlivější credentials z celého software lifecycle.

Package install je code-execution surface

Package managers podporují hooks:

preinstall
install
postinstall
prepare

a native addon flows mohou spustit node-gyp.

Instalace tedy znamená:

dependency resolution
+
download
+
potenciální code execution

Je jisté, že šlo o TeamPCP?

JFrog, Socket a další výzkumníci spojují payload s Mini Shai-Hulud a příbuznými variantami.[3][4]

Přesná atribuce operátora však není veřejně definitivně doložena.

Možné je:

  • pokračování stejného aktéra,
  • zbytkový přístup,
  • reuse známého malware,
  • copycat.

JFrog tuto nejistotu výslovně zmiňuje.[4]

Proč se Mini Shai-Hulud vrací?

Tato rodina kampaní cílí na credential theft, CI/CD, GitHub, package registries a propagaci.[12]

Opakující se model:

proniknout do release cesty
→ získat publish authority
→ vydat důvěryhodně vypadající package
→ spustit se na developer/CI hostu
→ hledat další credentials

Květnový útok na TanStack byl technicky jiný

Dne 11. května 2026 byl zasažen repository Router/Start.[11]

Útok kombinoval:

  1. pull_request_target,
  2. GitHub Actions cache poisoning,
  3. extrakci OIDC tokenu z paměti runneru.

Výsledek:

42 packages
84 škodlivých verzí

[11]

To není stejný root cause jako 28. srpna.

Query byl čistý i v květnu

TanStack ve svém oficiálním postmortemu uvedl, že napaden byl pouze Router/Start a Query patřil mezi nepostižené rodiny.[11]

Proto:

květen → Router/Start
srpen → nezávislý codegen pro Query

Ani jeden případ neznamená kompromitaci @tanstack/react-query.

Květnový incident měl skutečný downstream dopad

OpenAI potvrdilo, že dvě zařízení zaměstnanců byla květnovým TanStack/Mini Shai-Hulud útokem zasažena.[13]

OpenAI popsalo credential-focused aktivitu a omezenou exfiltraci credential materiálu z části repozitářů, ale nenašlo důkazy o přístupu k user data ani kompromitaci produkčních systémů nebo IP.[13]

Krátké exposure window tedy nemusí znamenat malý dopad.

Srpen vs květen

Květen

fork PR
→ pull_request_target
→ poisoned cache
→ trusted release obnoví cache
→ OIDC token z paměti
→ publish

[11]

Srpen

fork PR
→ veřejný komentář "npm publish"
→ privileged workflow checkoutuje PR
→ pnpm install spustí attacker code
→ job už má id-token: write
→ Trusted Publishing

[1][2]

Srpnová cesta byla jednodušší.

Jak zjistit, zda projekt byl zasažen?

Prohledejte všechny lockfiles, SBOM a historické CI záznamy pro všech 10 verzí.[1]

Kontrolujte:

package-lock.json
pnpm-lock.yaml
yarn.lock
bun.lock
SBOM
CI install logs
dependency caches

Aktuální package.json nestačí.

Důležité IOC

Veřejně známé indikátory:[1][2][5]

3FWCvzduYZg.js
binding.gyp
is_it_this_simple.js
nu.js
/tmp/trinnyyyy-*/bun
/tmp/*/updater.py

Hledejte také neočekávané stahování Bun, gh auth token, Git Credential Manager calls a nečekaný node-gyp v balíčku, který nepotřebuje native code.

Co dělat po zasažené instalaci?

GitHub advisory a StepSecurity doporučují považovat host za potenciálně kompromitovaný.[1][2]

Minimální reakce:

1. zastavit buildy
2. izolovat host
3. použít oddělený čistý stroj
4. rotovat všechny dostupné credentials
5. invalidovat sessions
6. prověřit GitHub/npm/cloud audit logs
7. odstranit dependency caches
8. zahodit artifacts ze zasaženého runneru
9. rebuildovat z čistých vstupů

Nestačí rotovat pouze npm token.

Které verze jsou bezpečné?

GitHub advisory označuje 3.0.2 jako known-good a uvádí, že verze publikované před 28. srpnem nejsou tímto incidentem zasažené.[1]

StepSecurity uvádí čisté předchůdce:

0.5.3
1.6.2
2.2.0
3.0.2

[2]

Dne 31. srpna npm znovu ukazuje:

latest = 3.0.2

[6]

Co upstream opravil?

Podle advisory:[1]

  • odstranil issue_comment trigger,
  • release přesunul na tag push,
  • revoked npm Trusted Publisher,
  • rotoval long-lived tokeny,
  • vrátil latest na 3.0.2,
  • odstranil pre dist-tag,
  • deprecated všech 10 škodlivých verzí,
  • požádal npm o odstranění.

Snyk rovněž klasifikuje kompromitaci jako Critical s CVSS 9.6, což potvrzuje závažnost spuštění škodlivého kódu při instalaci.[8] Relevantní jsou také další hardening kroky, které TanStack po květnovém incidentu zavedl pro cache, workflows a release pipeline.[14]

Jak hardenovat GitHub Actions

  • Nikdy nespouštět untrusted PR code v privileged job.
  • U comment-driven workflows ověřovat authorization aktéra.
  • id-token: write dát pouze skutečnému publish jobu.
  • Oddělit build od publish.
  • Používat trusted trigger nebo approval.
  • Third-party Actions pinovat na commit SHA.[9]

Jak hardenovat instalaci dependencies

Praktické kontroly:

  • lockfiles,
  • frozen installs,
  • minimum release age/cooldown,
  • monitoring nových publishů,
  • package-size anomaly detection,
  • lifecycle-script policy,
  • sandboxované CI,
  • omezení outbound network,
  • malicious-package scanning vedle CVE,
  • SBOM,
  • minimální credentials na runnerech.

npm Trusted Publishing zůstává užitečné.[10]

Ale:

Trusted Publishing

musí být spojeno s:

Trusted Workflow Design

Produkční checklist

Dependencies

  • Lockfile je povinný.
  • CI blokuje neočekávané změny lockfile.
  • Minimum release age/cooldown.
  • Nová verze nejde okamžitě do produkce.
  • Sledujeme package-size změny.
  • Kontrolujeme install scripts.
  • Neočekávané binding.gyp vyvolá alert.
  • Malware scanning doplňuje CVE scanning.

GitHub Actions

  • Fork code nikdy neběží privileged.
  • issue_comment má authorization gate.
  • pull_request_target pouze když je nutný.
  • GITHUB_TOKEN má least privilege.
  • id-token: write jen kde je potřeba.
  • Publish vyžaduje trusted trigger.
  • Build a publish jsou oddělené.
  • Actions jsou pinované na SHA.
  • Comment-driven automatizace má negativní test pro neautorizovaného uživatele.
  • Release workflow nikdy necheckoutuje kód z nedůvěryhodného forku.

npm

  • Trusted Publisher je omezen na nezbytné workflows.
  • Nemáme zbytečné long-lived publish tokeny.
  • Publish monitorujeme realtime.
  • Neplánovaný release vyvolá alert.
  • Provenance ověřujeme, ale nepovažujeme za malware verdict.
  • Máme runbook pro deprecation/revocation.

Runnery a endpointy

  • CI runner je ephemeral.
  • Workspace obsahuje minimum secretů.
  • Cloud credentials jsou short-lived.
  • SSH keys mají minimální scope.
  • Outbound traffic je monitorován.
  • Dependency install nemá široký přístup do infrastruktury.
  • Endpointy mají EDR/runtime monitoring.
  • Host lze rychle izolovat.

Incident response

  • Owner dependency incidentu je určen.
  • Umíme historicky hledat v lockfiles.
  • Umíme rychle vyčistit CI caches.
  • Umíme invalidovat sessions.
  • Máme mapu credentials dostupných runneru.
  • Rotace probíhá z clean machine.
  • Kontrolujeme neautorizované npm publishes.
  • Vyhodnocujeme GitHub audit logs.

Verdikt POLPROG

Kompromitace @7nohe/openapi-react-query-codegen je velmi dobrým příkladem toho, jak se v roce 2026 mění software supply-chain attacks.

Útočník nemusel:

hacknout npm
ukrást maintainerovo heslo
obejít 2FA
ukrást klasický publish token

Stačilo dostat untrusted code do workflow, který už měl legitimní publish identity.

Bezpečnostní hranice se tak posouvá k:

CI/CD
workflow triggers
OIDC
release authorization
dependency execution

Druhé ponaučení je provenance.

Platná provenance zde nezklamala. Správně potvrdila původ škodlivého buildu.

Třetí ponaučení je přesnost.

TanStack Query samotný kompromitován nebyl.

Napaden byl nezávislý nástroj jeho ekosystému.

K 31. srpnu jsou škodlivé verze známé, advisory zveřejněné, latest vrácené na 3.0.2 a release workflow upravený.[1][6]

Klíčová otázka pro JavaScript tým tedy není jen:

Používali jsme tento balíček?

Ale:

Může se v našem vlastním release pipeline dostat nedůvěryhodný input do jobu s publish authority?

Pokud odpověď není okamžitě jasná, je čas auditovat GitHub Actions.

Mini Shai-Hulud npm supply chain TanStack Query openapi-react-query-codegen GitHub Actions Trusted Publishing OIDC npm provenance DevSecOps

Často kladené otázky

Byl TanStack Query hacknut?

Ne.

Co bylo kompromitováno?

@7nohe/openapi-react-query-codegen.

Kolik verzí bylo škodlivých?

10.

Kdy?
  1. srpna 2026, hlavní vlna přibližně mezi 20:00 a 20:21 UTC.
Jaká je aktuálně čistá verze?

3.0.2.

Byl ukraden npm token maintainera?

Nebyl potřeba. Útok zneužil Trusted Publishing/OIDC.

Proč byla provenance platná?

Protože publikoval skutečný důvěryhodný workflow.

Je provenance k ničemu?

Ne. Potvrzuje původ, nikoli malware-free stav.

Může binding.gyp spustit kód během npm install?

Ano. V tomto incidentu byl zneužit node-gyp execution path.

Co dělat po instalaci zasažené verze?

Izolovat host, z čistého stroje rotovat credentials, prověřit logy a prostředí znovu čistě vybudovat.

Je TeamPCP jistý operator?

Veřejné důkazy nestačí pro definitivní atribuci této konkrétní vlny.

Je Trusted Publishing rozbité?

Ne v tomto jednoduchém smyslu. Hlavním problémem byl nebezpečný workflow design.

Zdroje a poznámky

  1. GitHub Security Advisory, GHSA-9pvf-vcx3-x239, 28. srpna 2026, přístup 31. srpna 2026.123456789101112131415161718192021222324
  2. StepSecurity, @7nohe/openapi-react-query-codegen Compromised Through an Exposed npm Publishing Workflow, 28. srpna 2026.12345678910111213141516
  3. Socket, OpenAPI React Query Codegen Compromised in Mini Shai-Hulud npm Supply Chain Attack, 28. srpna 2026.1234
  4. JFrog Security Research, Shai-Hulud Trinitite Hits @7nohe/openapi-react-query-codegen, 30. srpna 2026.12
  5. OSV, MAL-2026-15494, 28. srpna 2026.12
  6. npm, @7nohe/openapi-react-query-codegen, stav ověřen 31. srpna 2026.123456
  7. npm, @tanstack/react-query, stav ověřen 31. srpna 2026.12
  8. Snyk, Embedded Malicious Code affecting @7nohe/openapi-react-query-codegen, 28. srpna 2026.
  9. GitHub Docs, Securely using pull_request_target, přístup 31. srpna 2026.12
  10. npm Docs, Trusted publishing for npm packages, přístup 31. srpna 2026.123
  11. TanStack, Postmortem: TanStack npm supply-chain compromise, 11. května 2026, aktualizováno 15. května 2026.12345
  12. Aikido Security, Mini Shai-Hulud Is Back, 12. května 2026.
  13. OpenAI, Our response to the TanStack npm supply chain attack, 13. května 2026, později aktualizováno.12
  14. TanStack, Hardening TanStack After the npm Compromise, 12. května 2026, aktualizováno 15. května 2026.

Bylo to užitečné?

Odebírejte nové články e-mailem

Jeden krátký e-mail na každý nový článek znalostní báze. Žádný spam, odhlášení jedním kliknutím.

Váš e-mail používáme pouze k zasílání nových článků. Žádné sdílení s třetími stranami.

Zpět do znalostní báze