Kai Ole Hartwig — Blog
11 Min. Lesezeit
Hoch
Von

binding.gyp - ein npm-Supply-Chain-Worm, der node-gyp statt postinstall missbraucht — und CI/CD-Credentials erntet

4. Juni 2026. StepSecurity meldet einen aktiven, selbst-replizierenden npm-Worm, der nicht über die üblichen preinstall/postinstall-Hooks läuft, sondern eine binding.gyp-Datei einschleust: npm ruft daraufhin node-gyp auf, und der Angreifer nutzt dessen Shell-Expansion, um beim npm install stillschweigend Code auszuführen. Die Malware erntet Credentials aus npm, GitHub, AWS, GCP, Azure, HashiCorp Vault, Kubernetes und RubyGems, injiziert sich in GitHub-Actions-Workflows und veröffentlicht vergiftete Versionen weiterer Pakete des Opfers. Laufender Vorfall — die Liste der betroffenen Pakete wächst.

TL;DR — 90 Sekunden

Betroffen?

npm-Pakete in mehreren Maintainer-Accounts; bisher Dutzende vergiftete Versionen in Familien wie autotel-*, awaitly-*, executable-stories-* und node-env-resolver-* (plus Einzelpakete wie @vapi-ai/server-sdk, ai-sdk-ollama). Alle bekannten malicious Versionen wurden zwischen 3. und 4. Juni 2026 veröffentlicht. Die Liste wächst — die autoritative, laufend aktualisierte Aufstellung steht bei StepSecurity.

Risiko?

Stille Code-Ausführung beim npm install über binding.gyp/node-gyp (ohne postinstall-Hook), Credential-Diebstahl (npm/GitHub/AWS/GCP/Azure/Vault/Kubernetes/RubyGems), CI/CD-Worm-Ausbreitung und Workflow-Injection.

Sofortmassnahme?

Builds/CI gegen die bekannten Paketversionen prüfen, verdächtige binding.gyp in Dependencies suchen, betroffene Credentials rotieren, CI-Workflows auf injizierte setup-bun-Schritte prüfen.

Empfehlung?

Mid-Market und Enterprise: Lockfiles einfrieren, --ignore-scripts in CI erzwingen, Token-Scopes minimieren und kurzlebig halten, Audit der zuletzt aktualisierten npm-Dependencies.

Kritikalität?

high (referenziert das Hero-Badge — aktiv spreitender Worm, sofortiger Audit im 48h-Fenster).

Was ist das Problem?

Laut StepSecurity (laufender Vorfall, Stand 3. Juni 2026) läuft dieser Worm bewusst nicht über die preinstall/postinstall-Lifecycle-Hooks in der package.json — also genau die Stelle, auf die Security-Tools, Reviewer und npms eigene Audit-Systeme schauen. Stattdessen legt der Angreifer eine kleine binding.gyp-Datei ins Paket. Sobald npm eine binding.gyp sieht, ruft es automatisch node-gyp auf, um ein vermeintliches natives Addon zu kompilieren. Der Angreifer missbraucht dabei die Shell-Expansion im sources-Array:

 

{
  "targets": [
    {
      "target_name": "Setup",
      "type": "none",
      "sources": ["<!(node index.js > /dev/null 2>&1 && echo stub.c)"]
    }
  ]
}

 

Das führt beim Install stillschweigend node index.js aus. Der scripts-Block der package.json enthält nur legitime Build-Kommandos; es gibt keinen postinstall-Hook, der Verdacht erregt. Die binding.gyp ist laut StepSecurity nur rund 100 Byte gross — die dadurch getriggerte index.js dagegen 4,5 bis 4,9 MB obfuskierter Code.

Die Malware läuft laut StepSecurity in drei Stufen. Stufe 1 (obfuskierter Loader): Die Root-index.js dekodiert über eine ROT-N-Caesar-Chiffre ein inneres Skript, das anschliessend zwei AES-128-GCM-verschlüsselte Payloads mit hartkodierten Schlüsseln entschlüsselt. Stufe 2 (Runtime-Download): Die erste Payload lädt still die Bun-JavaScript-Runtime (v1.3.13) von GitHub in ein temporäres Verzeichnis — das gibt dem Angreifer eine schnelle, eigenständige Runtime, die im Node.js-Prozessbaum kaum Spuren hinterlässt. Stufe 3 (CI/CD-Worm): Die zweite Payload (~720 KB) ist der eigentliche Worm und läuft über die heruntergeladene Bun-Runtime.

Wer ist betroffen?

BetroffenNicht betroffenBedingungen / verschärfend
Projekte/CI, die eine vergiftete Version eines gelisteten Pakets ziehen (Familien autotel-*, awaitly-*, executable-stories-*/eslint-plugin-executable-stories-*, node-env-resolver-* sowie Einzelpakete wie @vapi-ai/server-sdk, ai-sdk-ollama, mountly, wrangler-deploy)Projekte ohne eine der betroffenen Versionen im Dependency-Baum (direkt oder transitiv)npm install läuft ohne --ignore-scripts; node-gyp verfügbar und durch die eingeschleuste binding.gyp getriggert
Entwickler-Maschinen und CI-Pipelines mit erreichbaren Cloud-/Registry-CredentialsReine Laufzeit-Umgebungen ohne npm-Install-Schritt und ohne erreichbare SecretsCredentials von npm, GitHub (inkl. PATs), AWS (inkl. IMDSv2/ECS-Task-Role), GCP, Azure (inkl. Key Vault), HashiCorp Vault, Kubernetes, RubyGems im Zugriff
Maintainer-Accounts, deren Tokens erbeutet werden — ihre eigenen Pakete werden weitervergiftetGestohlene npm-/RubyGems-Tokens erlauben Publish; GitHub-Token erlaubt Workflow-Push

StepSecurity bezeichnet den Vorfall ausdrücklich als „developing“ — die Liste der kompromittierten Pakete und Versionen wird laufend ergänzt. Die autoritative, aktuelle Aufstellung steht in der Quelle; ich verzichte hier bewusst darauf, eine Momentaufnahme als vollständig auszugeben.

Auswirkungen

Der Kern ist, dass die Code-Ausführung an der Stelle passiert, an der die üblichen Detektionen nicht hinschauen: nicht im postinstall, sondern im node-gyp-Build, den npm bei Anwesenheit einer binding.gyp selbst anstösst. Damit umgeht der Angreifer laut StepSecurity konventionelle Tools.

Die Folgen, die StepSecurity dokumentiert, sind die eines vollwertigen CI/CD-Worms. Erstens Credential-Harvesting: Die Malware durchsucht die Umgebung nach npm-Tokens, GitHub-Tokens und PATs, AWS-Access-Keys (inklusive der IMDSv2- und ECS-Task-Role-Endpunkte), GCP-Service-Account-Credentials, Azure-Client-Secrets und Key-Vault-Inhalten, HashiCorp-Vault-Tokens (über mehrere Dateipfade und die lokale Vault-API), Kubernetes-Service-Account-Tokens, RubyGems-API-Keys sowie Passwörtern aus 1Password-CLI, gopass und pass; zusätzlich extrahiert sie maskierte Secrets aus dem Prozessspeicher des GitHub-Actions-Runners. Zweitens Workflow-Injection: Mit gestohlenen GitHub-Tokens ändert der Worm CI/CD-Workflow-Dateien in Repos, in die das Opfer pushen kann, und schiebt einen setup-bun-Schritt plus einen Payload-Ausführungsschritt ein — so läuft er bei jedem künftigen CI-Job mit. Drittens Package-Poisoning: Mit gestohlenen npm-/RubyGems-Tokens fragt er alle vom Opfer verwalteten Pakete ab, lädt sie, injiziert die Payload und veröffentlicht neue, vergiftete Versionen — so springt der Worm von einem Account auf Dutzende Pakete. Viertens Exfiltration: Die erbeuteten Credentials werden mit einem hartkodierten RSA-Public-Key verschlüsselt und als „dangling commits“ (Commits, die von keinem Branch erreichbar sind) in angreiferkontrollierte GitHub-Repos geschoben — schwer über normales Repo-Browsing zu finden.

Eine CVE-Nummer gibt es für diese Kampagne nicht; es ist ein laufender Lieferketten-Vorfall, kein einzelner Produktfehler. Genau deshalb ist die operative Schwere hoch: Wer eine betroffene Version zieht, verliert potenziell die Schlüssel zu seiner gesamten Cloud- und Registry-Landschaft.

Mitigation / Sofortmassnahmen

Hinweis: Die folgenden Schritte sind meine operative Empfehlung auf Basis der dokumentierten Technik — keine vom Hersteller zertifizierte Anleitung.

Operational Decision Block

Schritt 1 — Installs absichern

 

# node-gyp-/Script-Ausfuehrung beim Install global unterbinden (CI und lokal)
npm config set ignore-scripts true
# oder pro Lauf:
npm ci --ignore-scripts

# Hinweis: --ignore-scripts unterbindet die automatische node-gyp-Ausfuehrung,
# die diese binding.gyp-Technik ausnutzt. Native Module muessen dann bewusst
# und kontrolliert gebaut werden.

 

Schritt 2 — Dependency-Baum auditieren

 

# Pruefen, ob eine betroffene Paketfamilie im Baum steckt (Beispiele anhand der
# laufend aktualisierten StepSecurity-Liste anpassen/erweitern)
npm ls autotel autotel-mcp awaitly node-env-resolver executable-stories-vitest 2>/dev/null

# Lockfile gezielt nach Paketnamen durchsuchen
grep -nE "autotel|awaitly|executable-stories|node-env-resolver|@vapi-ai/server-sdk|ai-sdk-ollama" package-lock.json

 

Schritt 3 — Credentials rotieren

 

Wenn eine betroffene Version installiert wurde (lokal oder in CI), als kompromittiert behandeln:
- npm-, GitHub- (inkl. PATs) und RubyGems-Tokens widerrufen und neu ausstellen
- AWS-/GCP-/Azure-Keys rotieren, Azure Key Vault pruefen
- HashiCorp-Vault- und Kubernetes-Service-Account-Tokens rotieren
- Passwort-Manager-CLI-Sitzungen (1Password/gopass/pass) als exponiert annehmen

 

Schritt 4 — CI-Workflows pruefen

 

# Auf injizierte setup-bun-Schritte in Workflows pruefen
grep -RInE "setup-bun|oven-sh/setup-bun" .github/workflows/

# Unerwartete Workflow-Aenderungen im Git-Verlauf sichten
git log --oneline -- .github/workflows/

Detection / Prüfung

IOCs direkt aus der von StepSecurity dokumentierten Technik abgeleitet.

Verdächtige binding.gyp in Dependencies finden

 

# binding.gyp-Dateien im node_modules-Baum auflisten
find node_modules -name binding.gyp

# Auf die charakteristische Shell-Expansion im sources-Array pruefen
grep -RIn "<!(" node_modules --include=binding.gyp

# Auffaellig: sehr kleine binding.gyp (~100 Byte) neben sehr grosser index.js (mehrere MB)
find node_modules -name binding.gyp -size -200c

 

Bun-Runtime-Download und Spuren

 

Laut StepSecurity laedt Stufe 2 die Bun-Runtime (v1.3.13) von GitHub in ein
temporaeres Verzeichnis. Pruefpunkte:
- unerwartete Bun-Binaries in Temp-Pfaden auf Dev-Maschinen/CI-Runnern
- ausgehende Verbindungen zu GitHub-Release-Assets waehrend npm install
- in Workflows: ein setup-bun-Schritt, der nicht aus Ihrem Repo stammt

 

Exfiltrations-Muster

 

Exfiltration erfolgt laut StepSecurity als "dangling commits" in
angreiferkontrollierte GitHub-Repos (von keinem Branch erreichbar).
- ungewoehnliche, nicht referenzierte Commits in eigenen Repos pruefen
- GitHub-Audit-Log auf unerwartete Workflow-/Content-Pushes sichten

Betreiberempfehlung

Mittelstand

Zuerst eingrenzen, dann rotieren. Prüfen Sie Lockfiles und CI-Caches gegen die betroffenen Paketnamen; wenn eine Version drinsteckt, behandeln Sie alle in der Pipeline erreichbaren Tokens als kompromittiert und rotieren Sie sie. Schalten Sie --ignore-scripts in CI scharf — das unterbindet die automatische node-gyp-Ausführung, die diese Technik ausnutzt. Native Module bauen Sie danach bewusst und kontrolliert.

Enterprise

Zusätzlich: kurzlebige, eng gescopte CI-Credentials (OIDC statt langlebiger Keys), Egress-Kontrolle auf Build-Runnern, und ein Audit, das zuletzt aktualisierte npm-Dependencies und Workflow-Änderungen korreliert. Die Workflow-Injection ist hier der gefährlichste Teil — ein einmal eingeschleuster setup-bun-Schritt persistiert über künftige CI-Läufe.

Kubernetes / Container

Build-Images neu bauen, sobald eine betroffene Version im Baum war; alte Layer transportieren die vergiftete Version weiter. Service-Account-Tokens rotieren, IMDS-Zugriff auf Build-Pods restriktiv halten (die Malware zielt explizit auf IMDSv2/ECS-Task-Role).

Deklarative Stacks (NixOS / Talos / Flatcar)

Pin auf bekannte gute Versionen, reproduzierbarer Rebuild, und der Vorteil der deklarativen Spur: Welche npm-Version wann in welchen Build floss, ist nachweisbar — genau das, was die Eingrenzung eines Lieferketten-Vorfalls beschleunigt.

Was ich konkret getan habe

Ich behandle Lieferketten-Worms als Pipeline-Disziplin-Frage, nicht als einzelnes Paket. Für meine betreuten Stacks heisst das: --ignore-scripts ist in CI Default, native Builds laufen kontrolliert und nicht beiläufig beim Install; CI-Credentials sind kurzlebig und eng gescopt; Egress auf Build-Runnern ist eingeschränkt. Anlassbezogen habe ich Lockfiles und Caches gegen die von StepSecurity gelisteten Paketfamilien geprüft und einen Sweep auf binding.gyp-Dateien mit der charakteristischen <!(-Shell-Expansion gefahren.

Die Lehre aus diesem Vorfall ist nicht „noch ein npm-Worm“, sondern die Verschiebung der Ausführungsstelle: Wer Detektion und Policy nur an preinstall/postinstall festmacht, sieht eine binding.gyp-getriggerte node-gyp-Ausführung nicht. Das reiht sich in das Muster ein, das ich bei Shai-Hulud (@antv) und der Miasma-/@redhat-cloud-services-Welle beschrieben habe — nur dass hier der Trigger-Mechanismus neu ist. Deshalb gilt für mich: Install-Scripts (inklusive impliziter node-gyp-Builds) sind in CI standardmässig aus, und Token-Reichweite wird so klein wie möglich gehalten, damit ein einzelner kompromittierter Install nicht die ganze Cloud-Landschaft öffnet.

Häufige Fragen zum binding.gyp-npm-Worm

Schützt npm install --ignore-scripts gegen die binding.gyp-Technik?+

Ja, in der Praxis: Der Angriff nutzt die automatische node-gyp-Ausführung, die npm bei Anwesenheit einer binding.gyp anstösst. --ignore-scripts unterbindet diese Install-Ausführung. Native Module müssen dann bewusst und kontrolliert gebaut werden — das ist der Preis, und er ist es wert.

Warum greifen klassische postinstall-Scanner hier nicht?+

Weil kein postinstall-Hook existiert. Der scripts-Block der package.json enthält nur legitime Build-Kommandos; die Code-Ausführung läuft über die 100-Byte-binding.gyp und node-gyps Shell-Expansion im sources-Array. Tools, die nur Lifecycle-Hooks prüfen, sehen das laut StepSecurity nicht.

Welche Pakete sind betroffen?+

Bisher Dutzende Versionen in Familien wie autotel-*, awaitly-*, executable-stories-* und node-env-resolver-* sowie Einzelpakete wie @vapi-ai/server-sdk und ai-sdk-ollama, alle zwischen 3. und 4. Juni 2026 veröffentlicht. Es ist ein laufender Vorfall — die autoritative, aktuelle Liste steht bei StepSecurity, nicht hier.

Welche Credentials sind im Risiko, wenn ein Build betroffen war?+

Laut StepSecurity: npm-, GitHub- (inkl. PATs), RubyGems-Tokens, AWS-Keys (inkl. IMDSv2/ECS-Task-Role), GCP-, Azure- (inkl. Key Vault) Credentials, HashiCorp-Vault- und Kubernetes-Tokens sowie Passwörter aus 1Password-CLI/gopass/pass. Zusätzlich werden maskierte Secrets aus dem GitHub-Actions-Runner-Speicher extrahiert. Im Ernstfall: alles rotieren, was die Pipeline erreichen konnte.

Wie erkenne ich, ob der Worm sich in unsere CI eingenistet hat?+

Prüfen Sie Ihre Workflow-Dateien auf einen nicht von Ihnen stammenden setup-bun-Schritt (grep -RIn "setup-bun" .github/workflows/) und den Git-Verlauf der Workflows auf unerwartete Änderungen. Laut StepSecurity injiziert der Worm genau diesen Schritt, damit er bei jedem künftigen CI-Job mitläuft.

Gibt es eine CVE-Nummer oder einen Patch?+

Nein. Das ist eine laufende Lieferketten-Kampagne, kein einzelner Produktfehler — entsprechend gibt es keine CVE und keinen Hersteller-Patch. Die „Behebung“ ist operativ: betroffene Versionen meiden, Installs absichern, exponierte Credentials rotieren, CI-Workflows bereinigen.

Fazit

Dieser Worm ist technisch nicht spektakulärer als die npm-Wellen davor, aber er trifft einen blinden Fleck: Die Code-Ausführung wandert vom postinstall in den node-gyp-Build, den npm bei einer binding.gyp selbst anstösst. Wer Policy und Detektion nur an Lifecycle-Hooks festmacht, sieht das nicht. Die wirksame Antwort ist unspektakulär und bekannt: Install-Scripts in CI standardmässig aus (--ignore-scripts), native Builds bewusst und kontrolliert, Credentials kurzlebig und eng gescopt, Workflow-Änderungen überwacht. Weil der Vorfall laufend ist, gilt für die Paketliste die Quelle, nicht eine Momentaufnahme. Nicht dramatisieren, aber heute prüfen — die Reichweite eines einzigen kompromittierten Installs reicht hier bis in die gesamte Cloud- und Registry-Landschaft.

Quellen

Bevor der nächste Install Ihre CI-Secrets erntet — sprechen wir über Ihre Pipeline-Disziplin.

Ich prüfe, mitigiere und validiere Ihre npm-/CI-Lieferkette gegen Worms wie den binding.gyp-Vorfall.

Dependency- und Lockfile-Audit gegen die betroffenen Paketfamilien, --ignore-scripts-Durchsetzung in CI, Token-Scoping und Rotation, Workflow-Integritätsprüfung und Egress-Kontrolle auf Build-Runnern.

Plattformbetrieb statt Beratung-on-paper: Ich prüfe, mitigiere und validiere produktive Pipelines — von der SBOM-Inventur über die Stopgap-Massnahme bis zur Validierung.

Termin direkt vereinbaren

Über den Autor

Foto von Kai Ole Hartwig.

Kai Ole Hartwig

Freiberuflicher DevSecOps-Berater · OnlyOle Consulting

Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität. Heute freiberuflich: DevSecOps-Beratung, Schulungen und Softwareentwicklung.