Open Source ·
AntV ecosystem npm packages hit by TeamPCP
On 2026-05-19, TeamPCP took the shared atool npm account and published 639 malicious versions across 323 packages — most of the @antv ecosystem and a long tail of standalone neighbors. The bun-based dropper harvested CI/CD secrets and self-propagated via npm.
Part of Shai-Hulud hits npm and PyPI campaign
Hundreds of npm packages from Alibaba's @antv data-visualization stack, plus a long tail of widely used JavaScript utilities that happened to share the same maintainer account, were hijacked over a 90-minute stretch on the morning of May 19, 2026, and republished as a self-spreading credential stealer.
The packages were all owned by an npm account called atool, the shared publishing handle behind the @antv namespace, several smaller scopes, and a grab-bag of standalone libraries including echarts-for-react, timeago.js, and size-sensor. Researchers at Socket, who first reported the activity, said the attacker pushed 639 malicious versions across 323 packages in two automated waves between 01:39 and 02:56 UTC; npm's own publication records still account for 566 of those versions across 283 packages, in two bursts at 01:56 and 02:05. SafeDep and StepSecurity confirmed roughly the same scope. Wiz, which named the attacker TeamPCP, said the broader "Mini Shai-Hulud" wave that day reached 1,055 versions across 502 packages spanning npm, PyPI, and Composer, most of it driven by this single compromised account.
According to Socket, the attacker used two delivery paths. Most packages had their package.json rewritten with a preinstall or postinstall of bun run index.js, with the script dropped at the package root. A second set instead pointed at a poisoned commit in the antvis/G2 GitHub repository through optionalDependencies, where a prepare hook ran the same code. The payload was a half-megabyte, heavily obfuscated Bun script that walked the disk for credentials covering every major cloud provider, Kubernetes, HashiCorp Vault, SSH, and database connection files, then read /proc/*/mem on GitHub Actions runners to pull masked CI/CD secrets out of the Runner.Worker process in plaintext. It behaved like a worm: given any usable npm token, it would validate the credential, enumerate every package the account could publish, fetch each package's latest tarball, inject the same dropper, and republish. Exfiltration ran to t.m-kosche.com over HTTPS disguised as OpenTelemetry trace traffic, with bodies wrapped in AES-256-GCM and RSA-OAEP, falling back to GitHub itself when that channel failed and committing harvested data to public repositories on stolen developer accounts. Socket counted between 2,200 and 2,500 such repositories by the end of the day. On infected hosts the payload also rewrote editor and CI configuration files and, on macOS, registered a LaunchAgent for a backdoor named kitty.
Socket said it flagged most malicious versions within six to twelve minutes of publish, with a median of 6.7 minutes, and npm reclassified them as known malware. Wiz attributed the operation to TeamPCP at moderate confidence based on shared infrastructure, the firedalazer dead-drop tag, payload kinship with other campaigns, and reuse of the kitty backdoor and Dune-themed repositories elsewhere in the same wave. The same backdoor surfaced a few hours later in the Nx Console VS Code extension compromise (see [[nx-console]]), and Wiz said credentials stolen in the @antv wave were later used to publish a malicious Microsoft Python SDK to PyPI (see [[durabletask-pypi]]). The cross-ecosystem aggregate lives on [[shai-hulud-here-we-go-again]]; this record holds the @antv-account evidence.
Notes
- The compromised maintainer was the shared npm account atool, email [email protected], covering the @antv, @lint-md, @openclaw-cn and @starmind scopes. Wiz tracked the same account's GitHub credentials entering microsoft/durabletask-python that day.
- Version lists here were derived from npm publication times, not a published table: 283 releases at 01:56 UTC and 283 more at 02:05 to 02:06. That is 566 versions across 283 packages, against Socket's 639; the rest have no npm record left.
- Three same-day releases at 01:44, 01:47 and 01:49 UTC sit outside the bursts and are still served. Their archives contain none of the campaign's files, so they are recorded as clean baselines rather than affected versions.
- The complete @antv/g2 5.5.8 archive was recovered from Huawei Cloud's historical npm mirror. Its SHA-256 and size match the values published by AntV and it includes the previously missing malicious index.js.
Appendix · Affected releases
- The SHA-256 applies specifically to 5.5.8. GitHub issue 7394 records the measured 2,306,515-byte npm tarball and its digest; npm now returns 404. MalwareBazaar, Triage and Malshare held no bytes under that digest on 2026-08-13.
Indicators
- fileindex.js
- commandbun run index.js
- file~/.local/share/kitty/cat.py
- file~/Library/LaunchAgents/com.user.kitty-monitor.plist
- file~/.config/systemd/user/kitty-monitor.service
- file.claude/settings.json
- file.claude/setup.mjs
- file.vscode/tasks.json
- file.vscode/setup.mjs
- file.github/workflows/codeql.yml
- domaint.m-kosche.com
- domainm-kosche.com
- ipv4185.95.159.32
- urlhttps://t.m-kosche.com:443/api/public/otel/v1/traces
- tagfiredalazer
- tagniagA oG eW ereH :duluH-iahS
- file_sha256cat.py: fb5c97557230a27460fdab01fafcfabeaa49590bafd5b6ef30501aa9e0a51142
- file_sha1cat.py: 783b4019fc5b942a29846132d28441c8fc31bed8
- file_md5cat.py: b06b126b9e26af03a7ef2f8b8e90d446
- accountatool (npm)
References
- Mini Shai-Hulud: TeamPCP Hits @antv Supply Chain - Wizwiz.io
- Shai-Hulud Here We Go Again - Mass npm Supply Chain Attack Hits the AntV Ecosystem - StepSecuritystepsecurity.io
- @antv Packages Compromised - Socketsocket.dev
- @antv/g2 5.5.8 malicious release report with measured tarball checksumgithub.com
- @antv/g2 5.5.8 retained package member listing - Socketsocket.dev
- Mini Shai-Hulud compromised AntV npm packages enable CI/CD credential theft - Microsoftmicrosoft.com
- Shai-Hulud Here We Go Again - JFrog Security Researchresearch.jfrog.com
Source record: oss/attacks/antv-npm/meta.yaml