# CanisterWorm: Self-Propagating Worm in the npm Supply Chain After the Trivy Attack
Attackers, following the compromise of Trivy, deployed the CanisterWorm worm, which infected dozens of npm packages. The malware uses ICP canisters on the Internet Computer blockchain for a resilient C2 server. This is the first documented abuse of ICP for payload retrieval, providing decentralized resistance to takedowns.
Infection and Propagation Mechanism
The attack chain starts with a postinstall hook in the compromised packages. The hook launches a loader that installs a Python backdoor. The backdoor connects to an ICP canister to retrieve the URL of the next payload.
The ICP canister implements the methods get_latest_link, http_request, and update_link. The latter allows the controller to change the URL in real time, updating executable files on all infected hosts without interrupting operations.
The backdoor polls the canister every 50 minutes with a fake User-Agent. If the URL contains youtube.com, the implant goes dormant. Activation occurs by switching to the real payload; old processes continue running in parallel.
Persistence is ensured by a systemd service named "pgmon", masquerading as PostgreSQL monitoring. The Restart=always directive restarts the backdoor 5 seconds after termination.
Affected packages:
- 28 in the @EmilGroup scope;
- 16 in the @opengov scope;
- @teale.io/eslint-config;
- @airtm/uuid-base32;
- @pypestream/floating-ui-dom.
Socket detected 141 malicious artifacts in 66+ unique packages.
Evolution of CanisterWorm to Full Automation
In versions 1.8.11–1.8.12 of @teale.io/eslint-config, a mutated variant integrates npm token theft into index.js. The findNpmTokens() function scans the environment during postinstall and launches deploy.js as a background process for self-propagation.
Deploy.js publishes malicious versions to all accessible packages using the stolen tokens. The worm, presumably generated by AI using Vibe technology, does not obfuscate its code.
The current payload in ICP is the test string "hello123", indicating a chain verification phase before a full attack.
A similar mechanism with youtube.com check was found in the trojanized Trivy 0.69.4 via sysmon.py, referencing the same ICP canister.
Comparison with Previous Campaigns
CanisterWorm follows the pattern of Shai-Hulud (September): the compromise of tinycolor spread to 40+ packages, then the worm infected 300+ via NpmModule.updatePackage and TruffleHog for credential validation.
Sha1-Hulud (November) affected 25,000+ repositories: the preinstall script setup_bun.js detected the Bun environment, launching bun_environment.js for data theft.
| Campaign | Affected Packages | Propagation Mechanism | Theft Tools |
|-------------|-------------------|-----------------------------------|------------------|
| Shai-Hulud | 300+ | NpmModule.updatePackage | TruffleHog |
| Sha1-Hulud | 25,000+ | preinstall/setup_bun.js | bun_environment |
| CanisterWorm| 66+ | postinstall/deploy.js + ICP C2 | findNpmTokens |
Key Takeaways
- First use of ICP canisters for C2 in malware: decentralization makes takedowns difficult.
- Automatic propagation: token theft + deploy.js turns installations into infection vectors for CI/CD and dev machines.
- Resilience: systemd with Restart=always + parallel processes + dynamic update_link.
- Masquerading: services disguised as pgmon, dormant mode on youtube.com.
- Scale: from Trivy to 141 artifacts; evolution to full automation without manual deploys.
Companies Aikido Security, Endor Labs, JFrog, and Wiz confirm: this marks a shift from single compromises to exponential worm behavior in the npm ecosystem.
— Editorial Team
No comments yet.