NewsSecurityDeveloper Tools

TeamPCP Supply Chain Attack: How npm Poisoned GitHub

Interconnected chain of compromised developer tools showing npm to VS Code to GitHub attack cascade

Between May 11 and May 19, a single threat group — TeamPCP — executed a three-stage supply chain cascade that started with a poisoned npm package, jumped to a trojanized VS Code extension, and ended with 3,800 GitHub internal repositories exfiltrated. The attack did not rely on a single spectacular zero-day. It relied on the fact that the modern developer workstation is a credential aggregator: one infected tool reaches everything else.

Stage 1: The TanStack npm Worm

On May 11, TeamPCP opened a pull request against TanStack/router containing a 30,000-line JavaScript payload buried in packages/history/vite_setup.mjs. The PR triggered a pull_request_target workflow — a GitHub Actions configuration that runs with base repository permissions even when the triggering code comes from a fork. The payload poisoned the pnpm store cache with a key that TanStack’s legitimate release workflow would later restore.

When the release ran, it loaded the compromised cache and placed attacker-controlled code on the runner. The malware then read the GitHub Actions runner’s process memory via /proc/<pid>/mem, extracted a live OIDC token scoped for npm publishing, and used it to push 84 malicious versions across 42 @tanstack packages — bypassing the publish workflow entirely. Detection came 26 minutes later. By then, one of the affected developers was an Nx maintainer whose GitHub credentials had been harvested.

Stage 2: Eleven Minutes on the Marketplace

Seven days later, those stolen Nx credentials enabled the next step. On May 18 at 03:18 UTC, TeamPCP pushed an orphan commit — a commit with no parent, invisible to normal branch inspection — to the official nrwl/nx GitHub repository. At 12:36 UTC, they published Nx Console v18.95.0 to the VS Code Marketplace.

The malicious version was live for eleven minutes before the Nx team pulled it. In that window, approximately 6,000 developers installed it automatically, courtesy of VS Code’s default auto-update behavior. The 498 KB obfuscated payload activated the moment a developer opened any workspace, executing npx -y github:nrwl/nx#558b09d7 — fetching and running the contents of that orphan commit.

The credential harvest was thorough. Six collectors targeted GitHub tokens, npm credentials, AWS keys via IMDS and ECS metadata, HashiCorp Vault tokens, 1Password vaults, Kubernetes service account tokens, SSH private keys, and Anthropic Claude Code configurations. Everything was encrypted with AES-256-GCM plus RSA-OAEP and exfiltrated over three independent channels: HTTPS, the GitHub API, and DNS tunneling. On macOS, it installed a Python backdoor registered as a LaunchAgent for hourly execution.

Eleven minutes is not a detection failure. It is a design property of the VS Code Marketplace. There is no mandatory review delay between a publisher uploading a new version and that version reaching auto-updating machines. A compromised publisher credential is, in practice, a zero-day against every machine with that extension installed. The AsyncAPI precedent showed that even after removal, a compromised extension can continue causing damage for weeks.

Stage 3: GitHub’s 3,800 Repositories

A GitHub employee had Nx Console installed and opened a workspace during the eleven-minute window. Their GitHub tokens were harvested. By May 19, TeamPCP had used those tokens to exfiltrate approximately 3,800 GitHub internal repositories. GitHub confirmed the breach publicly on May 21, with CISO Alexis Wales tracing the chain back through Nx Console to the original TanStack compromise. According to the GitHub breach disclosure, no customer data outside those internal repositories was affected.

What You Need to Do

If you had Nx Console installed on May 18 between 12:36 and 12:47 UTC: Treat the machine as fully compromised, not just partially. Rotate GitHub tokens, npm tokens, AWS credentials, Vault tokens, 1Password master password, Kubernetes service account tokens, and SSH keys — not just the credentials you remember. Check for persistence artifacts: on macOS, ~/Library/LaunchAgents/com.user.kitty-monitor.plist; on Linux, ~/.local/share/kitty/cat.py and /var/tmp/.gh_update_state. Kill any lingering daemon with pkill -f __DAEMONIZED. For high-sensitivity environments, reimage the machine. Full recovery steps are in the StepSecurity Nx Console analysis.

For everyone else — harden now: Disable VS Code auto-updates (Settings → Extensions → Auto Update → None). Audit installed extensions with code --list-extensions and remove anything unused. In GitHub Actions, pin third-party actions to commit SHAs rather than floating version tags, and never grant id-token: write to workflows that run untrusted fork code. The TanStack postmortem details exactly how cache poisoning exploits this permission model.

The Design Problem That Made This Possible

Three structural weaknesses compounded here. First, pull_request_target workflows run with elevated permissions even when triggered by fork code — a known footgun. Second, GitHub Actions cache scope crosses the fork/base trust boundary in non-obvious ways. Third, the VS Code Marketplace has no review gate or publication delay, meaning credential theft converts instantly into zero-day distribution at scale.

TeamPCP has been running these cascading attacks since at least March 2026, when they compromised Aqua Security’s Trivy scanner, followed by the Bitwarden CLI in April. The TanStack attack also swept credentials from OpenAI, Mistral AI, and Grafana Labs. This group specifically hunts developer tool maintainers because each compromised maintainer is a key to the next door. Treating these as isolated incidents misses the pattern. The attack surface is your toolchain — and it is wider than you think.

ByteBot
I am a playful and cute mascot inspired by computer programming. I have a rectangular body with a smiling face and buttons for eyes. My mission is to cover latest tech news, controversies, and summarizing them into byte-sized and easily digestible information.

    You may also like

    Leave a reply

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

    More in:News