Trivy Flaw Sparks Widespread npm CanisterWorm Outbreak Supply Chain Attack via Trivy Impacts 47 Packages
Mar 21, 2026 // 11:33 - Niko Dunn


The individuals responsible for the supply chain attack that targeted the widely used Trivy scanner are believed to be launching additional attacks. These attacks have resulted in the compromise of numerous npm packages using a new, self-spreading worm named CanisterWorm.

The malware’s name comes from its use of an ICP canister (tamper-resistant smart contracts on the Internet Computer blockchain) as a dead drop resolver. This is the first known instance of an ICP canister being used to obtain the command-and-control (C2) server, according to Aikido Security researcher Charlie Eriksen said.

A list of the affected packages is provided below:

  • 28 packages under the @EmilGroup scope
  • 16 packages under the @opengov scope
  • @teale.io/eslint-config
  • @airtm/uuid-base32
  • @pypestream/floating-ui-dom

This development occurs one day after attackers used a stolen credential to release malicious versions of trivy, trivy-action, and setup-trivy, which contained a credential-stealing component. TeamPCP, a cybercriminal group focused on cloud environments, is suspected of orchestrating these attacks per reports.

The compromise of npm packages involves a postinstall hook executing a loader, which then installs a Python backdoor. This backdoor connects to the ICP canister dead drop to retrieve the URL of the next-stage payload. The decentralized nature of the dead drop makes it difficult to take down and highly resilient.

“The canister’s controller can change the URL at any moment, distributing fresh binaries to all compromised hosts without altering the implant itself,” Eriksen stated.

Persistence is achieved through a systemd user service, which is configured to automatically restart the Python backdoor after a 5-second delay if the service is terminated. This is accomplished using the “Restart=always” directive. The systemd service disguises itself as PostgreSQL tooling (“pgmon”) to avoid detection.

As previously stated, the backdoor communicates with the ICP canister every 50 minutes, using a spoofed browser User-Agent, to retrieve the URL in plaintext. This URL is then used to download and execute the payload.

“If the URL contains youtube[.]com, the script ignores it,” Eriksen explained. “This is the canister’s inactive state. The attacker activates the implant by pointing the canister to a legitimate binary and deactivates it by switching back to a YouTube link. When the attacker updates the canister with a new URL, every infected machine retrieves the new binary on its subsequent check. The previous binary continues to run in the background since the script never terminates old processes.”

Notably, Wiz identified a similar youtube[.]com-based kill switch in the compromised Trivy binary (version 0.69.4), which also contacts the same ICP canister via another Python dropper (“sysmon.py”). Currently, the URL returned by the C2 is a Rickroll YouTube video.

The Hacker News discovered that the ICP canister offers three methods: get_latest_link, http_request, and update_link. The final method enables the attacker to modify the behavior and deliver a genuine payload at any point.

Furthermore, the packages include a “deploy.js” file, which the attacker manually executes to spread the malicious payload to every package accessible via a compromised npm token in a programmatic way. The worm, which is thought to be generated using an artificial intelligence (AI) tool, does not attempt to hide its functionality.

“This is not triggered by npm install,” Aikido stated. “It is a separate tool that the attacker utilizes with stolen tokens to maximize the impact.”

Adding to the problem, a newer variant of CanisterWorm found in “@teale.io/eslint-config” versions 1.8.11 and 1.8.12 has been observed to self-propagate without any manual intervention.

Unlike “deploy.js,” which was a standalone script that the attacker needed to execute using stolen npm tokens to upload a malicious version of the npm packages to the registry, the updated version integrates this functionality into “index.js” within a findNpmTokens() function. This function is executed during the postinstall phase to steal npm authentication tokens from the victim’s machine.

The key difference is that the postinstall script, after installing the persistent backdoor, tries to find all npm tokens from the developer’s environment. It then immediately launches the worm with these tokens by starting “deploy.js” as a completely detached background process.

Interestingly, the attacker reportedly replaced the ICP backdoor payload with a dummy test string (“hello123”), likely to verify that the entire attack sequence is functioning correctly before implementing the actual malware.

“The attack moves from ‘compromised account publishes malware’ to ‘malware compromises more accounts and publishes itself,'” Eriksen explained. “Every developer or CI pipeline that installs this package and has access to an npm token becomes an unwitting propagation vector. Their packages are infected, their downstream users install these packages, and if any of them have tokens, the cycle repeats.”

(This story is still developing. Please check back for updates.)

#attack  #canisterworm  #chain  #flaw  #impacts  #news  #npm  #outbreak supply  #packages  #sparks  #trivy  #via  #widespread   —   News