Ethersphere's bee-js 13.3.0 and Swarm Desktop 0.56.2 Shipped a Wallet Stealer and Backdoor After Attackers Hijacked the Release Pipeline

Attackers used stolen CI credentials to publish signed, notarised and provenance-backed malicious releases of Swarm's bee-js npm library and Swarm Desktop that steal node wallet keys and install backdoors on Windows, macOS and Linux.
Attackers used Ethersphere's own release automation to publish booby-trapped versions of two tools for the Swarm decentralised storage network: the npm library @ethersphere/bee-js 13.3.0 and the desktop app Swarm Desktop 0.56.2. Both stole node wallet keys and passwords and installed a backdoor on Windows, macOS and Linux. Both have been withdrawn. The project's GitHub advisory (GHSA-hh7j-5m3j-23pf) says any computer that installed or ran them "should be considered fully compromised".
What Happened
On 9 November 2026, bee-js 13.3.0 was the latest version on npm from 00:09 to 01:25 UTC. Swarm Desktop 0.56.2 appeared on GitHub at about 00:36 UTC and stayed up for about 8.5 hours.
Both releases came from the project's bee-worker automation account, with no signed commits and no pull requests. A maintainer wrote that 0.56.2 "was published by an attacker using stolen CI credentials". Security researchers say activity from a second account, belonging to a long-time maintainer, was also involved. How the attackers got in has not been explained.
Exposure was small but real. Researchers estimate about 10 downloads of the npm package, some of them by scanners and mirrors. Swarm Desktop 0.56.2 reached 65 downloads by 08:27 UTC, including researchers, and the built-in updater could offer it within about 10 minutes to Windows x64 PCs and Apple Silicon Macs. Intel Macs were never offered it, and Linux installs do not auto-update. No theft of funds had been reported at the time of writing.
Technical Details: How the Pipeline Was Abused
- bee-js: a GitHub release triggered the npm publishing workflow, which needed no approval and published in 73 seconds. Because the real workflow built the package, it carried valid provenance. Provenance shows where a package was built, not whether anyone reviewed it.
- Swarm Desktop: the attackers manually started a build workflow that had access to the Apple and Windows signing certificates and needed no approval. Apple notarised the macOS app, so users saw only the normal first-launch prompt.
- Other packages, including swarm-cli, bee-dashboard and Swarm Desktop's source, accepted version ranges that included 13.3.0.
What the Malware Does
- Loader: a few lines download and run more code from the attacker's server with the user's permissions. In bee-js it runs as a postinstall script, so installing the package is enough. Nobody has to import it. In Swarm Desktop it runs on every app start.
- Wallet theft: it looks for
config.yamlanddata-dir/keys/swarm.key. The key is an encrypted keystore, but its password sits in plain text inconfig.yaml. Together they let attackers take xDAI and xBZZ tokens, chequebook funds and stake. - Backdoor on Linux and macOS: a Go remote shell researchers call evjawbreaker, hidden in
~/.solidityand run as a user service (Linux) or a LaunchAgent (macOS). It reads its command-and-control address from an Ethereum smart contract, so the operators can change it at any time. They updated it 29 minutes before the malicious bee-js code was added. - Backdoor on Windows: a genuine, ConnectWise-signed ScreenConnect client installed as a service and pointed at the attacker's relay. For administrators it uses a known UAC bypass and adds a Microsoft Defender exclusion. Non-admin users see the UAC prompt again every time they cancel it.
Researchers link the payloads, through a shared contract, relay and file naming, to fake Solidity-developer extensions on Open VSX in September and to the group behind the 2025 SleepyDuck extension.
Indicators of Compromise
- Domain:
api.frameworkmetrics[.]xyz(paths/v1/analytics,/v1/electron,/v1/assets/,/v1/swarm/report), HTTP headerX-Ethersphere: 1 193.57.9[.]155:4912(evjawbreaker C2),185.232.84[.]169:8041(ScreenConnect relay)- Ethereum contract
0xf8a900Db50b3331be6B768bA460BB59f3E40C344 ~/.solidity/, systemd unitsolidity-langsupport-runner.service, LaunchAgentcom.solidity.langsupport.runner, Windows serviceScreenConnect Client (5cbe79c9c25524df)
What To Do Now
Developers and CI owners:
# find the bad version in lockfiles and caches
grep -R "bee-js" --include=package-lock.json --include=yarn.lock --include=pnpm-lock.yaml . | grep "13.3.0"
npm ls @ethersphere/bee-js
- Pin 13.2.0 and purge cached 13.3.0 copies from internal registries and mirrors.
- If 13.3.0 was installed with scripts enabled, treat the machine or runner as compromised. From a clean computer, rotate every secret it could read.
Swarm Desktop users:
- Check
bee-desktop.logfor "Bee Desktop version: 0.56.2 (production)". The logs are in~/Library/Logs/Swarm Desktop/(macOS),%LOCALAPPDATA%\Swarm Desktop\Log\(Windows) or~/.local/state/Swarm Desktop/(Linux). - Install 0.56.3, which researchers say has the same code as 0.56.1 under a newly issued signing certificate. On Linux, replace the package manually.
- If 0.56.2 ever ran, move funds, chequebook and stake to a new key from a clean device.
On any affected machine: remove ~/.solidity/, the systemd unit or LaunchAgent, and the ScreenConnect service. Updating or uninstalling the app does not remove them. Rebuilding from a trusted image is safer.
Why It Matters
This attack defeated controls many teams rely on: npm provenance, code signing and Apple notarisation all worked as designed and all vouched for malware. Ethersphere now requires DevOps approval for signing jobs and runs them only from the main branch. Every project should check the same thing. Can a single token start a release or a signing job with no human approval? If so, that token is effectively the project's signing key.
