TeamPCP Supply-Chain Attack Compromises npm and PyPI Packages

Summary
TeamPCP compromised npm and PyPI packages using a credential-stealing worm. The report details a GitHub Actions cache-poisoning attack, exfiltration methods, destructive persistence, affected packages, and recommended response steps.
Key points
- The campaign compromised packages across npm and PyPI, including packages in the TanStack, UiPath and Mistral namespaces, plus guardrails-ai.
- The TanStack attack poisoned a GitHub Actions cache through a pull_request_target workflow, then abused runner OIDC tokens to publish malicious package versions.
- The payload steals CI/CD, cloud, Kubernetes, Vault and package-registry credentials, and can use stolen tokens to publish poisoned packages to spread further.
- Credentials were exfiltrated through git-tanstack[.]com, the Session messenger network, and GitHub API dead drops.
- On some developer systems, a persistent daemon monitors GitHub token revocation and may attempt to delete the home directory; the article reports that an updated payload fixed a related deletion bug.
- Wiz attributes the activity with high confidence to TeamPCP. The npm team was removing malicious versions from the registry.
- Security teams should check package lockfiles and CI logs, remove the gh-token-monitor persistence before revoking GitHub tokens, rotate exposed credentials, and block reported C2 infrastructure.
Article Details
- Attack Vectors
- A fork of TanStack/router was submitted through a pull_request_target workflow that checked out and executed attacker code, poisoning the GitHub Actions cache; later release workflows restored the cache, enabling OIDC token theft and malicious package publication.
- Compromised npm packages used an optional dependency pointing to an orphan commit that ran a payload through a prepare script, and also embedded router_init.js in package tarballs.
- Compromised @uipath packages used a preinstall script to download the Bun runtime and execute a payload.
- Malicious PyPI packages downloaded and executed a credential-stealing payload from git-tanstack.com/tmp/transformers.pyz.
- The payload stole CI/CD, cloud, Kubernetes, Vault, and package-registry credentials, then used stolen npm and GitHub Actions OIDC tokens to publish poisoned packages to repositories accessible to victims.
- Stolen credentials were exfiltrated through a typosquat domain, the Session messenger network, and GitHub API dead drops.
- On developer machines, a persistent daemon monitored GitHub tokens and attempted to wipe the user's home directory after token revocation.
- Defensive Notes
- Search lockfiles and CI logs for affected package versions, and inspect package roots for router_init.js or setup.mjs.
- Find and remove the gh-token-monitor daemon before revoking GitHub tokens to avoid triggering its destructive handler.
- If exposure is suspected, rotate GitHub and npm tokens, AWS and Vault credentials, Kubernetes service-account credentials, and CI/CD secrets.
- Inspect .claude/ and .vscode/ directories for router_runtime.js or setup.mjs.
- Block git-tanstack.com and *.getsession.org at DNS or proxy level.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | filev2[.]getsession[.]org | Session file server identified as part of the malware's exfiltration channel. |
| DOMAIN | git-tanstack[.]com | Typosquat C2 and credential-exfiltration domain used by the payload. |
| DOMAIN | seed1[.]getsession[.]org | Session network seed node used as part of the malware's exfiltration channel. |
| DOMAIN | seed2[.]getsession[.]org | Session network seed node used as part of the malware's exfiltration channel. |
| DOMAIN | seed3[.]getsession[.]org | Session network seed node used as part of the malware's exfiltration channel. |
| IPV4 | 83[.]142[.]209[.]194 | Payload server receiving credentials stolen by the Python variant. |
| SHA1 | 12f35b1081b17d21815b35feb57ab03d02482116 | Hash of the malicious setup.mjs package artifact. |
| SHA1 | 820fa07a7328b6cf2b417078e103721d4d8f2e79 | Hash of the malicious opensearch_init.js artifact. |
| SHA1 | e7d582b98ca80690883175470e96f703ef6dc497 | Hash listed for a malicious package artifact. |
| SHA256 | 1e8538c6e0563d50da0f2e097e979ebd5294ce1defe01d0b9fe361ba3bed1898 | Hash of a trojanized package tarball. |
| SHA256 | 2258284d65f63829bd67eaba01ef6f1ada2f593f9bbe41678b2df360bd90d3df | Hash of the malicious setup.mjs package artifact. |
| SHA256 | 2ec78d556d696e208927cc503d48e4b5eb56b31abc2870c2ed2e98d6be27fc96 | Hash of the malicious router_init.js package artifact. |
| SHA256 | ab4fcadaec49c03278063dd269ea5eef82d24f2124a8e15d7b90f2fa8601266c | Hash of the malicious router_init.js package artifact. |
| URL | hxxps[:]//git-tanstack[.]com | Typosquat domain identified as a credential-exfiltration channel. |
MITRE ATT&CK
T1059.006 · PythonThe Python package variant downloaded and executed a Python payload.T1059.007 · JavaScriptMalicious JavaScript package scripts, including prepare and preinstall scripts, executed the payload.T1102.002 · Bidirectional CommunicationThe malware used GitHub API repositories as dead drops for exfiltrated data.T1195.001 · Compromise Software Dependencies and Development ToolsThe operation poisoned package releases and distributed malicious versions through npm and PyPI.T1485 · Data DestructionAfter detecting token revocation, the daemon attempted to delete the user's home directory.T1543.001 · Launch AgentOn macOS, the malware established persistence with a LaunchAgent for gh-token-monitor.T1543.002 · Systemd ServiceOn Linux, the malware established persistence with a systemd user service for gh-token-monitor.T1555 · Credentials from Password StoresThe payload stole credentials, including cloud, registry, CI/CD, Kubernetes, and password-vault credentials.T1567 · Exfiltration Over Web ServiceThe malware exfiltrated credentials through a typosquat domain and the Session network.
Threat Actors
Malware
Products
1PasswordCPUs. It gathers a variety of information, of note for the first time this includes password vaults (1Password, Bitwarden) and exfiltrates it to 83.142.209[.]194, with GitHub as a fallback, in which case PUSH URAWSself-propagating worm. It targets CI/CD tokens (GitHub Actions OIDC, GitLab, CircleCI), cloud credentials (AWS IMDSv2, GCP, Azure), Kubernetes service accounts, HashiCorp Vault, and package registry tokens. It usesAzureIt targets CI/CD tokens (GitHub Actions OIDC, GitLab, CircleCI), cloud credentials (AWS IMDSv2, GCP, Azure), Kubernetes service accounts, HashiCorp Vault, and package registry tokens. It uses stolen npm tokens andBitwardengathers a variety of information, of note for the first time this includes password vaults (1Password, Bitwarden) and exfiltrates it to 83.142.209[.]194, with GitHub as a fallback, in which case PUSH UR T3MPRR is usedBunnamespace were compromised. These packages use a preinstall script (node setup.mjs) that downloads the Bun runtime and executes the payload. This is the same delivery mechanism that was seen in the earlier SAPGCPworm. It targets CI/CD tokens (GitHub Actions OIDC, GitLab, CircleCI), cloud credentials (AWS IMDSv2, GCP, Azure), Kubernetes service accounts, HashiCorp Vault, and package registry tokens. It uses stolen npmGitHub ActionsThe TanStack compromise exploited a chain of three vulnerabilities in GitHub Actions. The attacker created a fork of the TanStack/router repository (renamed to zblgg/configuration to evade fork-list searches), thenHashiCorp VaultOIDC, GitLab, CircleCI), cloud credentials (AWS IMDSv2, GCP, Azure), Kubernetes service accounts, HashiCorp Vault, and package registry tokens. It uses stolen npm tokens and GitHub Actions OIDC tokens to publishKubernetesCI/CD tokens (GitHub Actions OIDC, GitLab, CircleCI), cloud credentials (AWS IMDSv2, GCP, Azure), Kubernetes service accounts, HashiCorp Vault, and package registry tokens. It uses stolen npm tokens and GitHubnpmOn 11 May 2026, TeamPCP launched a coordinated supply chain attack against the npm and PyPi ecosystems, compromising packages across multiple namespaces simultaneously.PyPIOn 11 May 2026, TeamPCP launched a coordinated supply chain attack against the npm and PyPi ecosystems, compromising packages across multiple namespaces simultaneously.SessionThe payload exfiltrates stolen credentials via three redundant channels: a typosquat domain (git-tanstack[.]com), the decentralized Session messenger network, and GitHub API dead drops using stolen tokens.
Countries
IranIf the package is executed on a system with location settings in Israel or Iran (via timezone and language) it invokes random.randint(1,6) and if that equals 2, it plays an mp3 file at full volume and runs rm -rf,IsraelIf the package is executed on a system with location settings in Israel or Iran (via timezone and language) it invokes random.randint(1,6) and if that equals 2, it plays an mp3 file at full volume and runs rm -rf,Russia