Back to News
Cyber Attack

Trivy Supply Chain Attack Triggers Self Spreading CanisterWorm Across npm

Trivy Supply Chain Attack Triggers Self Spreading CanisterWorm Across npm

A follow on wave of malicious npm packages has turned a recent Trivy supply chain compromise into something more alarming: a self spreading worm Aikido Security researcher Charlie Eriksen has dubbed CanisterWorm.

How the Attack Works

Aikido said the campaign has already touched 47 npm packages, including 28 in the @EmilGroup scope, 16 in @opengov, and packages such as @teale.io/eslint-config, @airtm/uuid-base32, and @pypestream/floating-ui-dom.

Eriksen said the malware uses an Internet Computer Protocol canister as a dead drop resolver, making it the first publicly documented case of an ICP canister being used specifically to fetch command and control infrastructure.

In simple terms, the canister acts like a remote mailbox where the attacker can change the next download link without changing the code already planted on victim machines.

The infection chain starts with a postinstall hook. When a developer or CI system installs one of the packages, the hook launches a loader that drops a Python backdoor.

That backdoor contacts the canister every 50 minutes with a spoofed browser User Agent to retrieve a plaintext URL for the next stage payload. The URL is then parsed and executed.

Because the canister is decentralized, Eriksen said it is harder to take down than a normal server.

Control and Persistence

The Hacker News said the canister exposes three methods, get_latest_link, http_request, and update_link, and that update_link lets the attacker change what infected hosts fetch at any time.

Eriksen said, “The canister controller can swap the URL at any time, pushing new binaries to all infected hosts without touching the implant.” That design gives the attacker a flexible way to rotate payloads without updating the malware on each device.

Persistence is handled through a systemd user service that waits five seconds before restarting the backdoor if it is killed.

The service uses Restart=always and hides in plain sight by pretending to be PostgreSQL tooling under the name pgmon.

The goal is simple: keep the backdoor alive long enough to keep polling the canister and pulling down whatever comes next.

The backdoor also has a built in dormant mode.

Eriksen explained that if the canister returns a youtube.com link, the script skips execution.

He said the attacker can arm the implant by pointing the canister at a real binary and disarm it by switching back to a YouTube link.

At the time of reporting, the command and control URL reportedly points to a rickroll YouTube video, which suggests the attackers were testing the chain before turning on a live payload.

Spreading to More Packages

There is also a manual spreading component. Aikido said the attacker uses a deploy.js file to push the malicious payload to every npm package reachable with stolen tokens.

“This isn’t triggered by npm install,” Aikido said.

“It’s a standalone tool the attacker runs with stolen tokens to maximize blast radius.” In other words, one stolen npm token can let the attacker poison several packages at once.

A later variant appears to remove the need for that manual step.

In versions 1.8.11 and 1.8.12 of @teale.io/eslint-config, Eriksen said the worm can collect npm authentication tokens from the victim’s environment in a findNpmTokens() function inside index.js and launch deploy.js automatically as a detached background process during the postinstall phase.

That means a single install can immediately lead to new malicious package uploads if a developer or build server has access to npm credentials.

One interesting detail is that the payload was briefly replaced with the test string “hello123”, which Eriksen said likely helped the attacker verify that the full chain was working before loading the real malware.

The broader warning is clear.

As Eriksen put it, “This is the point where the attack goes from compromised account publishes malware to malware compromises more accounts and publishes itself.”

Wiz previously flagged a related trojanized Trivy binary, version 0.69.4, that also reached the same ICP canister through a different Python dropper named sysmon.py.

Taken together, the reports from Aikido, Wiz, and The Hacker News show a campaign built to spread through trusted developer tools, steal credentials, and keep moving as long as it finds fresh tokens.

#Cybersecurity #SupplyChainAttack #npm #Trivy #Malware #Infosec