Der Bitwarden-CLI-Supply-Chain-Angriff vom 22. April 2026: Ablauf, Indikatoren und Remediation
Am Abend des 22. April 2026 ist eine malwaregeladene Version des offiziellen Bitwarden-CLI-npm-Pakets in der Registry aufgetaucht. @bitwarden/[email protected] war zwischen 17:57 und 19:30 ET, also rund 93 Minuten, auf npm abrufbar. Bitwarden spricht in der eigenen Stellungnahme von etwa 334 Installationen in diesem Fenster. [1][2]
Der Angriff lief nicht über einen klassisch gestohlenen Publisher-Token, sondern laut den Analysen von Socket, JFrog und Aikido über eine Kompromittierung in Bitwardens eigener CI/CD-Pipeline. Der betroffene Release-Workflow hatte legitime npm-Trusted-Publishing-Rechte, aus npm-Sicht hat damit der autorisierte Workflow das Paket veröffentlicht, nur eben mit einer injizierten bw1.js-Datei als preinstall-Hook. Security-Researcher Adnan Khan äußert im The-Hacker-News-Bericht die Einschätzung, dass dies seiner Kenntnis nach der erste öffentlich dokumentierte Kompromiss eines Pakets unter npm Trusted Publishing ist. [3]
Für Organisationen, die Bitwarden CLI in Entwicklungs-, Build- oder Secrets-Management-Prozessen einsetzen, heißt das konkret: Wenn zwischen Mittwochabend und Nacht irgendwo ein npm install oder npm ci lief, das @bitwarden/cli in Version 2026.4.0 gezogen hat, sind die Credentials dieses Hosts als kompromittiert zu behandeln. Dieser Artikel geht durch den technischen Ablauf, die bekannten Indikatoren und die Remediationsschritte, die jetzt anstehen.
Was genau veröffentlicht wurde
Betroffen ist ausschließlich die npm-Distribution von Bitwarden CLI, Version 2026.4.0. Alle anderen Bitwarden-Auslieferungswege sind nicht betroffen: [1][4]
- Die über die Bitwarden-Website ausgelieferten, signierten Binaries.
- Die Chrome-Extension und alle anderen Browser-Plugins.
- Die Bitwarden-Desktop-Apps, Mobile-Apps und Self-hosted-Server.
- Der Bitwarden MCP Server und weitere ergänzende Pakete.
- Der Bitwarden-Passwort-Manager-Kerndienst (Vault-Daten).
Bitwarden erklärt in der offiziellen Stellungnahme: [1]
no evidence that end user vault data was accessed or at risk, or that production data or production systems were compromised.
Die saubere Version 2026.4.1 steht auf der offiziellen GitHub-Release-Seite bereit. Version 2026.4.0 sollte in keinem Szenario weiter verwendet werden, und die Node-Modules-Caches aller Build-Maschinen müssen gelöscht werden, auf denen sie gelandet sein könnte.
Chronologie
Die Zeitangaben beziehen sich auf US-Ostküstenzeit (ET), ergänzt durch MESZ in Klammern: [1][2]
- 22. April 2026, 17:57 ET (23:57 MESZ):
@bitwarden/[email protected]wird durch den kompromittierten CI/CD-Workflow auf npm veröffentlicht. - 22. April 2026, 19:30 ET (01:30 MESZ am 23. April): Bitwardens Security-Team hat die Kompromittierung erkannt, den npm-Release deprecated und die zugehörigen Credentials revoked.
- 23. April 2026: Bitwarden veröffentlicht die offizielle Stellungnahme sowie Version
2026.4.1auf GitHub. Mehrere Security-Firmen (Socket, JFrog, Aikido, OX Security) publizieren parallel technische Deep-Dives.
Das Zeitfenster von rund 93 Minuten ist für ein Incident dieser Klasse kurz, was vor allem an der Sichtbarkeit des Pakets und an der Hintergrundaktivität einer parallel laufenden Angriffsserie liegt, die in der Berichterstattung als "Checkmarx-Supply-Chain-Kampagne" geführt wird. Security-Firmen ordnen den Bitwarden-Fall dort mit unterschiedlichen Cluster-Labels ein: Aikido verwendet Shai-Hulud: The Third Coming, JFrog TeamPCP. Die Serie ist seit Frühjahr 2026 dokumentiert und hat zuvor weitere Developer-Tool-Pakete getroffen. [2][5][6]
Der Angriffsvektor: CI/CD-Takeover, kein Token-Theft
Das eigentlich Interessante an diesem Vorfall liegt nicht darin, was gestohlen wurde, sondern wie die bösartige Version den Weg in die Registry gefunden hat. Der @bitwarden/cli-Release-Workflow war laut verfügbaren Analysen bereits auf npm Trusted Publishing (OIDC) umgestellt. Das ist die Mechanik, die klassische long-lived Publisher-Token obsolet machen soll: Ein spezifischer GitHub-Actions-Workflow darf Pakete per kurzlebigem OIDC-Token veröffentlichen, ohne dass ein dauerhaftes npm-Secret im Repository liegt.
Der Angriff zielte nicht auf einen Bypass des OIDC-Modells ab. Stattdessen wurde der legitime Publish-Workflow modifiziert beziehungsweise zur Ausführung gebracht. Aikido Security benennt konkret den Publish-Workflow publish-ci.yml als Eintrittspunkt: [5]
The attacker bypassed Bitwarden's trusted publishing controls by infecting the CI/CD pipeline itself.
Wie der Angreifer in die Pipeline gekommen ist, ist öffentlich nicht im Detail veröffentlicht. Socket und JFrog beschreiben für die Gesamtserie ein Standardvorgehen, das sich nicht zwingend 1:1 auf Bitwarden übertragen lässt, aber als Referenzmuster dient: [2][6]
It enumerates repositories the token can write to, lists Actions secrets, creates a branch, commits a workflow file, waits for the workflow to run, downloads the resulting artifact, and then deletes the branch and workflow run. [6]
Wichtig für die Einordnung von Trusted Publishing: Der Mechanismus schützt zuverlässig gegen den Leak eines long-lived Publisher-Tokens. Gegen einen Angreifer, der Schreibzugriff auf das Repository hat oder den autorisierten Release-Workflow zum Laufen bringen kann, hilft er nicht. Der nächste logische Baustein sind gehärtete Workflows selbst (siehe Abschnitt "Warum der Fall strukturell wichtig ist").
Die Nutzlast: bw1.js
Der eigentliche Schadcode steckt in einer zusätzlichen Datei namens bw1.js, die im Paket-Tarball mitgeliefert und über einen preinstall-Hook aus package.json getriggert wird. preinstall ist einer der drei npm-Lifecycle-Hooks (preinstall, install, postinstall), die bei jedem npm install mit den vollen Rechten des installierenden Benutzers laufen, ohne Sandbox und ohne explizite Bestätigung. preinstall feuert dabei vor dem eigentlichen Dependency-Setup. [2][6]
Als Interpreter nutzt die Payload nicht Node, sondern Bun v1.3.13. Das ist dasselbe Muster, das in den parallel analysierten Kompromittierungen der Kampagne zu sehen war. Die Bun-Nachlade-URL (github.com/oven-sh/bun/releases/download/bun-v1.3.13/) ist in den Netzwerk-IOCs dokumentiert, was nahelegt, dass der Payload Bun bei Bedarf selbst zieht. Das macht ihn in Umgebungen lauffähig, in denen Node-Policies greifen, Bun aber nicht. Zusätzlich ist der Payload gzip- und base64-codiert und in bw1.js als Loader eingebettet. [2]
Vor der Ausführung prüft der Payload die Host-Locale. Bei russischer Locale beendet sich das Skript still. Ein solches geografisches Self-Opt-out ist ein in der Malware-Landschaft seit Jahren beobachtetes Muster, erlaubt aber keine harte Attribution. [2]
Was der Payload tut
JFrogs Analyse beschreibt drei sequentielle Credential-Sammlungs-Wellen: [6]
1. Filesystem-Scan nach Developer-Credentials. Die Payload liest gezielt typische Entwickler-Credentials-Pfade:
~/.ssh/(private Keys,known_hosts,config)~/.git-credentialsund Git-Config-Dateien mituser.password~/.npmrc(npm-Token)~/.aws/credentialsund~/.aws/config(AWS Access Keys)~/.config/gcloud/credentials.db(Google-Cloud-OAuth-Refresh-Tokens)- Azure-CLI-Tokens via
azd-CLI-Ausgabe
Zwei zusätzliche Zieldateien, die in älteren Shai-Hulud-Wellen nicht in dieser Form dokumentiert waren, sind besonders bemerkenswert: [6]
~/.claude.json(Hauptkonfiguration von Claude Code, enthält OAuth-Token-Caches und MCP-Server-Definitionen samt dort eingebetteten Secrets)~/.kiro/settings/mcp.json(MCP-Konfiguration einer weiteren Agent-Toolchain)
Die Angreifer haben ihre Zielkataloge damit explizit um AI-Developer-Tooling und MCP-Server-Credentials erweitert. Wer Claude Code, Cursor oder vergleichbare Agents mit MCP-Server-Integrationen einsetzt, sollte diese Konfigurationsdateien als Credential-Quelle verstehen, nicht nur klassische Cloud-Token.
2. Environment- und Laufzeitabfrage. Der Payload ruft gh auth token auf, um das GitHub-CLI-Token zu ziehen, und scannt process.env nach Pattern-Matches auf ghp_ (GitHub Personal Access Token) und npm_ (npm auth token). Laut Socket-Analyse liest er in GitHub-Actions-Runnern zusätzlich den Runner.Worker-Memory aus, um nicht nur exponierte, sondern auch bereits "masked" Secrets der aktuellen Job-Ausführung zu extrahieren. [2][6]
3. GitHub-Actions-Secret-Extraktion. Wenn der gestohlene GitHub-PAT Schreibrechte hat, wird der Trick mit dem selbst eingecheckten Workflow wiederholt, um Secrets aus weiteren Repositories des Opfers herauszuziehen. Damit skaliert der Schaden über die eigentlich betroffene Maschine hinaus: Jeder infizierte Entwickler-Host kann potenziell den Zugriff auf alle Repository-Secrets öffnen, auf die sein PAT schreiben kann. [2][6]
Exfiltration
Die gesammelten Daten werden verschlüsselt, bevor sie das System verlassen: [6]
Generates a random 32-byte AES key ... Encrypts the AES key with an embedded RSA public key using OAEP-SHA256 ... Encrypts the compressed payload with AES-256-GCM.
Die primäre Exfiltrationsadresse ist:
- Domain:
audit.checkmarx[.]cx/v1/telemetry - IP:
94.154.172.43
Die Wahl des Hostnamens dürfte bewusst auf Tarnung abzielen: audit.checkmarx.cx klingt wie eine Telemetry-Endpoint der Firma Checkmarx und würde in einer schnellen Netzwerklog-Durchsicht nicht sofort als verdächtig auffallen. Die .cx-Top-Level-Domain (Weihnachtsinsel) ist nicht Teil der offiziellen Checkmarx-Domain-Landschaft, die primär unter checkmarx.com operiert.
Der Fallback-Mechanismus ist subtiler und damit gefährlicher für Umgebungen, die den primären Endpoint geblockt haben: Aikido berichtet, dass der Payload unter dem Account des Opfers ein öffentliches GitHub-Repository anlegt und dessen Commit-Messages als Dead-Drop nutzt. JFrog ergänzt, dass PATs über den Commit-Message-Marker LongLiveTheResistanceAgainstMachines gestaged und alternative Exfil-Domains über signierte Commits mit dem Marker beautifulcastle verteilt werden. Damit fließen die gestohlenen Daten über ein Plattform-Primitive, das in nahezu jeder Firewall als regulärer "GitHub-Traffic" durchgeht. [5][6]
Ein weiteres Persistenz-Primitiv schließt die Kette: Der Payload schreibt Backdoor-Zeilen in ~/.bashrc und ~/.zshrc, damit der Schadcode auch nach Neustart der Shell wieder aktiv werden kann. Gleichzeitig legt er die Artefakte /tmp/tmp.987654321.lock und /tmp/_tmp_<Unix-Epoch>/ als Run-Indikator und Staging-Verzeichnis an. [2]
Selbstidentifikation: Shai-Hulud: The Third Coming
Im Payload ist laut Aikido der String Shai-Hulud: The Third Coming eingebettet. Das ist die Eigenbezeichnung der Operation und eine direkte Rückverknüpfung zu den zwei vorangegangenen Shai-Hulud-Wellen. Das Dune-Vokabular (Shai-Hulud, Fremen, Sandwurm) zieht sich durch die Kampagne und ist in den Namen der automatisch erstellten GitHub-Repositories sichtbar, die als Exfil-Dead-Drops dienen. [5]
JFrog ordnet den Bitwarden-Vorfall unter dem Cluster-Label "TeamPCP" ein, das seit Frühjahr 2026 eine Serie vergleichbarer Operationen betreibt. Gemeinsames Muster: Developer-Tools, die tief in Build-Pipelines sitzen, werden gezielt kompromittiert. Jeder Entwickler, der solche Tools installiert, ist damit ein potenzieller Einstiegspunkt in die gesamte CI-Infrastruktur seiner Organisation.
Indicators of Compromise (IOCs)
Konsolidiert aus den öffentlichen Analysen von Socket, JFrog und Aikido (Stand: 24. April 2026): [2][5][6]
| Kategorie | Wert |
|---|---|
| Paket | @bitwarden/[email protected] (npm) |
| Malicious File | bw1.js im Paket-Tarball |
| Loader SHA-256 | 18f784b3bc9a0bcdcb1a8d7f51bc5f54323fc40cbd874119354ab609bef6e4cb |
| Payload SHA-256 | 8605e365edf11160aad517c7d79a3b26b62290e5072ef97b102a01ddbb343f14 |
| C2 Primary (Domain) | audit.checkmarx[.]cx/v1/telemetry |
| C2 Primary (IP) | 94.154.172.43 |
| Bun-Loader-URL | github.com/oven-sh/bun/releases/download/bun-v1.3.13/ |
| Dead-Drop-Marker | LongLiveTheResistanceAgainstMachines, beautifulcastle |
| Self-ID-String | Shai-Hulud: The Third Coming |
| Filesystem IOC 1 | /tmp/tmp.987654321.lock |
| Filesystem IOC 2 | /tmp/_tmp_<Unix-Epoch>/ |
| Filesystem IOC 3 | package-updated.tgz (im Staging-Verzeichnis) |
| Persistenz | Zeilen in ~/.bashrc und ~/.zshrc |
Detection: Wie prüfe ich, ob ich betroffen bin?
Die Prüfung läuft auf drei Ebenen.
Ebene 1: Paket-Spuren auf Hosts und in Projekten. Auf allen Maschinen, auf denen Bitwarden CLI per npm installiert wurde (Entwickler-Laptops, CI-Runner, Container-Images), folgende Checks laufen lassen:
# Lokal installierte globale Version
npm list -g @bitwarden/cli
# In allen Lock-Files nach der kompromittierten Version suchen
# (npm, pnpm, yarn, bun)
grep -rFl '"@bitwarden/cli"' \
--include="package-lock.json" \
--include="pnpm-lock.yaml" \
--include="yarn.lock" \
--include="bun.lockb" . 2>/dev/null
# npm ab v5 verwendet content-addressable Storage (cacache).
# Tarballs sind per SHA-Hash benannt, nicht per Paketname.
# Gezielt im Index (index-v5) nach dem Paket-Spec suchen:
grep -rlF 'bitwarden/cli/-/cli-2026.4.0' ~/.npm/_cacache/index-v5/ 2>/dev/null
# Wer auf Nummer sicher gehen will, bereinigt den Cache vollständig:
# npm cache clean --force
Ebene 2: Forensische Marker auf dem Host. Auch wenn die 2026.4.0-Version bereits weg ist, sind die Nebenwirkungen einer einmaligen Ausführung persistent:
# Staging-Artefakte
ls -la /tmp/tmp.987654321.lock /tmp/_tmp_*/ 2>/dev/null
# Shell-Profile-Backdoor (verdächtige Zeilen)
grep -En 'bun|bw1|checkmarx\.cx|LongLiveThe' ~/.bashrc ~/.zshrc 2>/dev/null
# Unbekannte Repos im eigenen GitHub-Account (Dune-Namen)
gh repo list --limit 200 --json name | grep -Ei 'shai|hulud|fremen|muaddib|arrakis'
Ebene 3: Netzwerk-Logs. In SIEM-, Proxy- und Firewall-Logs gezielt nach Verbindungen zu audit.checkmarx[.]cx bzw. 94.154.172.43 im Zeitfenster rund um den 22. und 23. April 2026 suchen. Alle Treffer sind als Incident zu behandeln. Auch DNS-Logs liefern hier belastbare Signale, selbst wenn die eigentliche HTTPS-Verbindung nicht geloggt wurde.
Remediation: Schritt für Schritt
Wenn einer der Detection-Schritte anschlägt oder bereits der Verdacht besteht, dass auf einer Maschine im relevanten Zeitfenster npm install @bitwarden/cli lief, gilt: Credentials dieses Hosts sind als kompromittiert zu behandeln. [1][2][4]
Sofortmaßnahmen:
- Auf Version
2026.4.1aktualisieren, aber nicht zwingend per npm: Die signierten Binaries von der offiziellen Bitwarden-GitHub-Release-Seite sind der konservativere Weg. - Shell-Profile-Backdoor entfernen:
~/.bashrcund~/.zshrcbereinigen, auf andere Shell-Konfigurationsdateien spiegeln (~/.profile,~/.config/fish/config.fish). - Staging-Artefakte löschen:
/tmp/tmp.987654321.lock,/tmp/_tmp_*.
@bitwarden/[email protected] deinstallieren und npm-Cache bereinigen:
npm uninstall -g @bitwarden/cli
npm cache clean --force
Credential-Rotation. Alles, worauf der Payload hätte zugreifen können, muss ersetzt werden:
- GitHub: Alle PATs des betroffenen Benutzers widerrufen und neu ausstellen. Org-Admins sollten die Workflow-Runs des Benutzers der letzten Tage auditieren, insbesondere auf gelöschte Branches und gelöschte Runs.
- GitHub Actions Secrets: Secrets aller Repositories, auf die der Benutzer Schreibzugriff hatte, rotieren. OIDC-basierte Secrets sind per Definition kurzlebig; lange Fernzugriffs-Tokens (AWS, GCP, Azure via Service Principal) müssen prioritär rotiert werden.
- npm: Alle persönlichen npm-Tokens widerrufen. Projekte mit klassischen Automation-Tokens in CI auf Trusted Publishing migrieren, sofern noch nicht geschehen.
- SSH: Alle privaten Schlüssel aus
~/.ssh/als kompromittiert ansehen. Public Keys aus GitHub, GitLab, Bitbucket, Servern entfernen; Schlüssel neu generieren. - Cloud-Credentials: AWS Access Keys, GCP Service-Account-Keys, Azure Service Principal Credentials rotieren.
~/.aws/credentialsneu schreiben, aktive Sessions invalidieren. - AI-Tool-Credentials: Claude-Code-OAuth-Sessions invalidieren, MCP-Server-Konfigurationen prüfen, darin enthaltene API-Keys (Anthropic, OpenAI, Cloudflare, GitHub etc.) rotieren. Dieser Punkt fehlt in den meisten bestehenden Incident-Runbooks.
- Bitwarden-eigene Credentials: Obwohl Bitwarden berichtet, dass keine Vault-Daten abgeflossen sind, ist ein Master-Password-Wechsel und das Widerrufen aller Session-Tokens eines Benutzers, dessen Host
bw1.jsausgeführt hat, eine sinnvolle Defense-in-Depth-Maßnahme.
Warum der Fall strukturell wichtig ist
Drei Punkte bleiben hängen, auch unabhängig vom konkreten Vorfall:
Trusted Publishing allein genügt nicht. Die Umstellung von long-lived Publish-Tokens auf OIDC-basiertes Trusted Publishing ist ein substantieller Fortschritt gegen eine ganze Angriffsklasse, nämlich den Leak oder Phish eines Maintainer-Tokens. Wer die CI-Pipeline-Integrität damit als gelöst betrachtet, läuft aber weiter offen in die zweite Angriffsklasse. Der nächste logische Baustein ist das Härten der Workflows selbst: Pinning von Action-Refs auf Commit-SHAs statt @main-Tags, Read-only-Token-Default, branch-protection-gesicherte Release-Branches und Audit-Trails für jede Änderung am Publish-Workflow.
Der Zielkatalog der Angreifer umfasst mittlerweile AI-Tools. Dass ~/.claude.json und ~/.kiro/settings/mcp.json im Payload mitgelesen werden, ist ein klares Signal. MCP-Server, die mit Cloud-APIs, Ticketsystemen, Datenbanken und Secrets Managern sprechen, liefern ein modernes Credential-Bündel, das klassische Angreifer-Scripts so noch nicht auf dem Radar hatten. Wer MCP in Entwicklungsumgebungen produktiv einsetzt, sollte die MCP-Konfigurationsdateien in die Secrets-Inventur aufnehmen und MCP-Tokens mit kurzem Lifecycle und minimalem Scope betreiben.
npm-Install-Hooks sind reale Code-Ausführung. Die preinstall-, install- und postinstall-Hooks von npm laufen mit den vollen Rechten des installierenden Benutzers, bevor irgendein Code-Review, ein Scanner oder eine Policy-Engine zum Zug kommt. npm install ist damit funktional Code-Ausführung, und Hosts, die produktiv npm install von Paketen aus der öffentlichen Registry laufen lassen, gehören in dieselbe Vertrauenskategorie wie Maschinen, die beliebige Binaries aus dem Internet ausführen. Für CI-Runner und Build-Container lohnt sich der Blick auf --ignore-scripts als Default, mindestens für Production-Build-Schritte.
Quellenangaben
- [1] Bitwarden Statement on Checkmarx Supply Chain Incident | Bitwarden Community
- [2] Bitwarden CLI Compromised in Ongoing Checkmarx Supply Chain Campaign | Socket
- [3] Bitwarden CLI Compromised in Ongoing Checkmarx Supply Chain Campaign | The Hacker News
- [4] @bitwarden/cli:2026.4.0 infected with malware? | Bitwarden Community
- [5] Is Shai-Hulud Back? Compromised Bitwarden CLI Contains a Self-Propagating npm Worm | Aikido
- [6] TeamPCP Campaign Spreads to npm via a Hijacked Bitwarden CLI | JFrog Security Research
- [7] Bitwarden CLI Backdoored in Checkmarx Supply Chain Attack | CyberInsider
- [8] Bitwarden CLI Compromised: Inside the Shai-Hulud Supply Chain Attack | OX Security
- [9] Bitwarden CLI Compromised in Supply Chain Attack via GitHub Actions | Cybersecurity News