CanisterWorm: Steals npm Tokens and Spreads Via Compromised Publisher Accounts

Out in the open since March 20, 2026, a sneaky digital invader called CanisterWorm creeps through npm systems. It grabs login keys from developers while they work. Once inside, it spreads tainted code copies into every project linked to those accounts.

Researchers at Aikido Security first spotted it just after 8 p.m. UTC that day. By the next evening, chaos had grown – 135 harmful files had popped up. These appeared across 64 different software packages, hitting several company zones. Teams from Endor Labs noticed it too.

So did analysts at Socket and Wiz. Each group worked alone yet found the same trail. All point toward an old offender named TeamPCP.

The First Break Trivy Starts

A backdoor slipped in through a trusted channel. Not some misspelled name on a package site, not a fake login link either – instead, a modified copy of Trivy, a tool built to find weaknesses. Versions v0.69.4 up to v0.69.6 turned out to be infected; so did trivy-action and setup-trivy actions pulled from GitHub during three days in March 2026.

These tainted builds quietly pushed malware straight into software assembly lines. Since Trivy runs in countless automated workflows, attackers have reached deep using TeamPCP tools to gain control of dev workstations far beyond what typical scam packages ever achieve.

Machines that used those versions might have spilled everything: keys, tokens for npm, personal logins for GitHub, passwords for cloud systems, even secure shell secrets – gone without warning.
Infection Chain Spreads Through Postinstall Hook,, EnablingSelf-Replicationn.

A sneaky script wakes up the second a poisoned package lands on your machine. Hidden deep in the package.json, it runs without asking – no pop-ups, no noise. That post-install trick runs its job right after the install finishes.

A local .js file, often index.js, is quietly called behind the scenes. Smooth. Unnoticed. Done before you even know something has been downloaded.

Right away, index.js kicks off two tasks at once. Not just one thing happens – credentials get pulled from the victim machine, too. Looking through .npmrc files shows up everywhere: projects, home paths like ~/.npmrc, even system spots like /etc/npmrc.

Environment variables aren’t safe either; NPM_TOKEN and S are checked without delay. Meanwhile, something else unf: ds Base64-Encodedse64 string hides a Python script inside. That encoded piece is written to the filesystem in plain text.

This Python part runs later – it repeatedly reaches back to a server. Its job? Grab more program pieces whenever they appear online.

Right away, the stolen npm tokens go straight into another script – scripts/deploy.js – where the worm knows how to copy itself. From there, it logs into the npm registry using what it stole, checks which packages belong to the victim, then quietly bumps up the patch version of each one.

Instead of stopping, it pushes out corrupted versions under the user’s legitimate name. The whole process runs without help once started.

A single compromised account suddenly becomes a fast-moving source of contamination, spreading harmful updates across many dependent projects in moments. Anyone relying on those packages now faces exposure without warning.

Persistence Through PostgreSQL Monitoring Disguise

A hidden foothold on Linux machines comes to life when CanisterWorm sets up a user-level systemd task called pgm, crafted to look like a normal tool that watches PostgreSQL activity.

Hidden inside the ~/.config/systemd/user/ folder sits a file named pgmon .service, dropped there by the threat. Once in place, it turns on without delay and launches immediately. Restarting nonstop every half dozen heartbeats keeps it running even after someone tries to shut it down.

Even if the harmful software gets uninstalled later, this trick holds the door open through reboots and interruptions. Spotting trouble means typing systemctl –user status pgmon directly into any machine where suspicious packages may have been added.

Blockchain Command Systems That Survive Shutdown Attempts

What stands out about CanisterWorm isn’t flashy – it’s how it talks to its controllers. Instead of using regular domains that authorities might shut down, TeamPCP takes a different path. Communication slips through a canister sitting on the Internet Computer Protocol blockchain. This shift sidesteps old takedown methods.

A Python-based downloader checks in with that endpoint regularly. Traffic flows without hitting typical internet checkpoints. Control stays resilient because of where it lives. Not on servers. On chain.
Out there, hidden inside an ICP canister, sits a silent drop point that hands off the address for another malicious file.

That second piece gets stored under /tmp/pglog, then switched into runnable mode before starting up on its own. Since the data lives on a blockchain network, pulling it offline isn’t possible by pressuring hosts, grabbing domains, or filing legal demands.

This setup gives CanisterWorm staying power far beyond that of most supply chain threats. Stopping it means cutting access at firewalls or gateways to raw.icp0.io – blocking just the name won’t always cut the link when decentralization is in play.

Affected Packages and Organizational Scope

A few of the affected packages come from different team spaces, as well as some independent ones. Among them, certain releases have been verified as harmful.

Standalone packages:jest-preset-ppf(0.0.2),babel-plugin-react-pure-component(0.1.6),eslint-config-service-users(0.0.3),opengov-k6-core(1.0.2),cit-playwright-tests(1.0.1),react-leaflet-marker-layer(0.1.5),react-leaflet-cluster-layer(0.0.4)​.

Scoped packages:@leafnoise/mirage(2.0.3),@airtm/uuid-base32(1.0.2),@teale.io/eslint-config(1.8.10, 1.8.13–1.8.15)​

Inside @opengov/, you’ll find tools like form-renderer along with form-builder. Over at @emilgroup/, more pieces fit into place nearby.

Right away, check the package.json and package-lock.json files to see if you spot the specific packages or versions mentioned earlier.​

AI-Assisted Threat Development

Some researchers noted that Canister Worm’s code appears to have been shaped by artificial intelligence. Clear structure marks the harmful scripts, open in design, only hiding through Base64-encoding within Python – nothing more complex than that.

That way of building lines up with patterns seen when big language models write software, favoring clarity alongside correctness. Back then, near the end of 2025, Unit 42 had already spotted something similar during their investigation into Shai-Hulud worm attacks, noting shell scripts made in a similar way using AI helpers.

For those protecting systems, one thing is clear: the rise of machine-generated code makes it easier for attackers to build complex supply chain threats quickly, shortening the e time from idea to real-world harm.

Connection to GlassWorm

Something else was happening around the same time as CanisterWorm. Back in March 2026, experts spotted another push, GlassWorm, affecting over 430 projects on GitHub. Instead of traditional methods, it relied on Solana’s blockchain to send hidden commands via memo fields.

Odd spacing symbols, invisible to the eye, tucked malicious scripts into normal-looking code. What came next stole data straight from browsers crypto wallets, login details, SSH keys, even active sessions patterns in how these attacks moved, along with matching location clues, point to a single source. Chances are that neither effort stems from the same group.

That would mean TeamPCP isn’t just focused on one platform but spans both. Though nothing proves it fully, pieces fit too closely to ignore. This looks like careful planning, not random shots.

While separate on the surface, they might be two arms of a single strategy unfolding together. Timing matters here – it wasn’t weeks apart, just days. One name doesn’t tell the whole story when others run alongside. Behind each lies similar thinking, tools shaped alike, goals lined up without obvious differences.

It adds up to coordination most wouldn’t expect so fast after the first wave hit. Not luck. More like rehearsal paid off. Whoever built this knew where gaps lived before anyone patched them. Now what seemed scattered shows signs of rhythm instead. Two names.

Same shadow behind both. From the side, they look distinct. Up close? Harder to say. Especially since tactics shift mid-step yet still echo earlier moves, even small choices repeat – the kind only copycats usually mimic poorly. But this feels different.

Cleaner. Like notes passed between teammates who know the plan cold. You can miss it if you watch only one corner of the board.

Step back, thou,- and shapes start forming that weren’t visible before. A trail runs under everything. Quiet. Persistent. Built to last longer than attention spans do. Most won’t connect the ts until later. By then, the ground had already shifted.

Indicators of Compromise (IoCs)

IndicatorTypeDescription
~/.config/systemd/user/pgmon.serviceFile pathMalicious systemd persistence service
/tmp/pglogFile pathDownloaded secondary stage binary
/tmp/—pg_stateFile pathExecution state tracker
tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.ioC2 DomainICP blockchain C2 endpoint
NPM_TOKENNPM_TOKENSEnv variablesTargeted for credential harvesting

Immediate Mitigation Steps

  • Start by checking systems for signs of compromise. After that, update software only from a trusted source. Then isolate any machines showing unusual behavior. Next, review access logs for unusual activity patterns. Followed by changing passwords on critical accounts immediately. Finally, you confirm each step was completed before moving ahead.
  • Start by wiping every npm token tied to systems using Trivy versions 0.69.4 through 0.69.6. Machines active during March 19–22, 2,026 need full scrutiny – assume nothing is safe. Tokens linked to package installs from impacted scopes? Already gone. Consider each one exposed beyond recovery. There are no exceptions here. Full revocation isn’t optional; it’s required. Anything connectedton that window must be reset completel.y
  • Look whether it stays with systemctl –user status pgmon, then peek inside /tmppglog and check ~/.config/systemd/user/pgmon.service.
  • Shut down access to tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.io at the outer edge of the network, stopping ICP gateway traffic. This breaks the command-and-control link.
  • Better safe than sorry – pull broken package versions from npm by hand. A fresh update alone won’t shield users stuck on older, tainted releases
  • Start by turning off post-install scripts everywhere. Run npm config set ignore-scripts true where you develop and in CI/CD setups. This stops code from running during installs unless someone chooses it on purpose.
  • Start by rotating every nearby credential. GitHub personal access tokens might be compromised, so swap them out. Move on to cloud keys – those for AWS, GCP, or Azure – replace each without delay. Docker Hub logins could also be at risk; update those, too. Kubernetes configuration files? Change them just in case. Any of these might’ve been pulled during the second-phase attack.

Broader Implications

  • Something strange happened after Shai-Hulushowcased its supply chain in 2025. Now CanisterWorm says it’s not just some lab trick anymore – it sticks around, spreads on its own, follows a clear method.
  • Instead of vanishing when caught, command signals hide across blockchain networks built to survive takedowns. TeamPCP keeps adjusting how they launch these attacks, step by step, without rushing.
  • Public code tools blindly run setup files, hand out permanent access keys – what once felt safe now opens doors.
  • Trust alone won’t hold things together much longer if nobody checks what’s going on behind the scenes. Safer spaces might ignore install scripts unless proven necessary, rotate tight-limited upload rights frequently, and monitor actions in real time during build stages. Stopping the next wave starts well before infection finds its footing.

FAQ

Start by typing systemctl –user status pgmon – seeing that service up means trouble probably started. Another clue hides in /tmp/pglog; find it on the drive, and alarm bells should ring. Look back at what went out through npm publish, especially updates you never sent.

Running on the ICP blockchain keeps its C2 system beyond normal reach. When npm pulls harmful packages, that command channel still operates without interruption. Because standard domain shutdowns fail here, cutting off raw.icp0.io at the firewall becomes necessary. Only network-level denial stops communication effectively.

Site: thecybrdef.com

John

John is a cybersecurity reporter covering the latest cyber threats, data breaches, and security research. Focused on translating complex technical topics into clear, actionable insights. Dedicated to delivering accurate, timely news to inform and protect the digital community.

Related Posts

CanisterWorm Malware Attack Docker/K8s/Redis to Gain Access

Out in the open now, a fresh digital invader named CanisterWorm spreads fast through cloud spaces. Rather than grabbing power to mine coins, this one digs deep into systems to…

Silver Fox Attack Hits Japanese Businesses With Tax-Themed Phishing

Not long ago, someone spotted Silver Fox up to old tricks – phishing big companies in Japan again. This time around, tax forms act like bait. Workers click without thinking…

Leave a Reply

Your email address will not be published. Required fields are marked *