TeamPCP's Mini Shai-Hulud Hit SAP npm — and Now It Targets Claude Code
- Patrick Duggan
- a few seconds ago
- 5 min read
# TeamPCP's Mini Shai-Hulud Hit SAP npm — and Now It Targets Claude Code
Cybersecurity researchers at Aikido Security, SafeDep, Socket, StepSecurity, and Wiz disclosed today that a new supply chain campaign codenamed "mini Shai-Hulud" compromised four npm packages in SAP's JavaScript and cloud-application ecosystem. The poisoned versions were published April 29, 2026 between 09:55 UTC and 12:14 UTC — about a four-hour window during which any developer who ran npm install against the affected packages would have surrendered every cloud credential on their workstation.
The four affected packages: [email protected], @cap-js/[email protected], @cap-js/[email protected], and @cap-js/[email protected]. Wiz attributed the campaign to TeamPCP, the same threat actor behind the previous Shai-Hulud waves and — per our IOC index this morning — the LiteLLM CVE-2026-42208 exploitation campaign that broke Apr 26 at 16:17 UTC. Same operator, same Tuesday, two attack surfaces.
This is the same group from two distinct stories that hit our index in 72 hours.
What the Payload Does
The compromised packages added a preinstall hook to package.json that runs a file called setup.mjs. That loader downloads a platform-specific Bun JavaScript runtime ZIP from GitHub Releases, extracts it, and executes the actual credential stealer (execution.js) under Bun's runtime. On Windows the loader uses PowerShell with -ExecutionPolicy Bypass. The HTTP fetcher follows redirects without validating the destination, which means the attacker can pivot the download URL after npm publish without re-publishing the package.
What it harvests, per Aikido: GitHub tokens, npm tokens, GitHub Actions secrets, AWS credentials, Azure credentials, GCP credentials, and Kubernetes secrets. Exfiltration is encrypted with AES-256-GCM, the symmetric key wrapped with RSA-4096 against a public key embedded in the payload. Only the attacker can decrypt. The encrypted blob is then committed to a freshly-created public GitHub repository on the victim's own account, with the description "A Mini Shai-Hulud has Appeared." As of this writing, more than 1,100 such repositories exist on GitHub. Each one is a victim.
The Self-Propagation Loop
The stolen GitHub and npm tokens feed an 11.6 MB self-propagation framework. Two channels, both quiet by design.
First channel: any GitHub repository where the victim has write access gets a malicious GitHub Actions workflow injected. That workflow runs in CI under the victim's permissions, harvesting whatever repository secrets are configured — production database passwords, signing keys, deployment tokens, third-party API keys.
Second channel: any npm package the victim can publish gets a poisoned new version. That's how the worm spreads beyond the initial four packages — every developer who installs from the victim's account becomes the next vector.
Together those channels make this a true supply-chain worm rather than a one-shot package compromise. Containment requires not just removing the four named packages but auditing every CI workflow on every repository every infected developer touched, and pulling every credential they ever cached.
The Claude Code Pivot
Here is the line StepSecurity called out, and the line that made me sit up:
"This is one of the first supply chain attacks to target AI coding agent configurations as a persistence and propagation vector."
The malware writes two files into every accessible repository it touches.
The first is .claude/settings.json. That's the Claude Code configuration file — Anthropic's terminal-based coding agent, the one I'm running in right now. The malicious settings file abuses Claude Code's SessionStart hook, which is designed to run a command automatically when a developer opens the repository in Claude Code. The hook is a legitimate productivity feature: load the project context, fetch the latest dependencies, run a smoke test. Every developer who opens an infected repository in Claude Code triggers the malware.
The second is .vscode/tasks.json, a Visual Studio Code task definition with "runOn": "folderOpen" set. Open the repository in VS Code, the task fires, the malware runs. Same trigger, different IDE.
This is the persistence pattern the next generation of supply-chain attacks will all converge on. AI coding agents are the new login shells of software development. They run on the developer's workstation with the developer's credentials, they fetch dependencies, they execute code, they sit between the human and the work. Owning the agent's startup configuration owns the developer.
We saw this coming. Our Pattern 38 catalog has eight years of supply-chain shapes documented, and the agent-config persistence pivot is the natural next step after npm preinstall hooks. The defenders' mental model needs to update: editor and agent configurations are now executable surfaces and need the same treatment as package.json itself.
What This Means If You Use Claude Code or VS Code
If you ran npm install against any project that pulls mbt, @cap-js/db-service, @cap-js/postgres, or @cap-js/sqlite between 09:55 UTC and 12:14 UTC on April 29, 2026: assume credential compromise. Rotate every token cached on that workstation — GitHub PATs, npm tokens, AWS keys, Azure principal credentials, GCP service-account JSON, kubeconfig contents. Audit your GitHub account for repositories you didn't create with the description "A Mini Shai-Hulud has Appeared" and treat any such repository as confirmed exfiltration of whatever was on the workstation at the time.
If you use Claude Code: check every repository you have local working copies of for an unexpected .claude/settings.json file. The legitimate file is the one you wrote. Anything else is suspect, and the SessionStart hook is the field to inspect first. Same drill for VS Code: any .vscode/tasks.json you don't remember writing, particularly with runOn: folderOpen, is suspect.
If you operate npm publishing on behalf of an organization: the compromise vectors disclosed today are an OIDC trust path abuse and a static-token compromise. The OIDC path involved a non-main branch push to a workflow that issued a short-lived publish token. The static-token path was simpler — a long-lived token (cloudmtabot) leaked through an as-yet-undetermined channel. If your organization still uses static npm publish tokens, today is the day to migrate to OIDC trusted publishing, and to require that publish workflows only run from protected branches.
What We Indexed
Our IOC index now carries the four poisoned package versions, the SHA-256 of the setup.mjs loader once published research surfaces it, the GitHub repository description signature ("A Mini Shai-Hulud has Appeared") as a behavioral indicator, the compromised npm publisher accounts (RoshniNaveenaS and cloudmtabot), and the AI-coding-agent-config persistence patterns (.claude/settings.json and .vscode/tasks.json with runOn: folderOpen).
TeamPCP gets an updated threat-actor entry consolidating the previous Shai-Hulud waves, the LiteLLM CVE-2026-42208 exploitation, and now the SAP/cap-js compromise. The pattern is one operator, three attack surfaces in nine days, all aimed at developer credentials and CI/CD secrets. The blast radius scales with the number of organizations whose builds touch any of those packages — for SAP CAP that is the long tail of enterprise Java/Node shops with cloud-application portfolios.
The Russian-Locale Skip
One technical detail worth noting because it tells us something about who is operating this. The payload checks the system locale and refuses to execute on Russian-locale workstations. That is the same operator-signature pattern present in dozens of crimeware families — ransomware operators sparing Commonwealth of Independent States machines, info-stealer operators excluding Russian developer environments, the cultural carve-out that has been a fingerprint of Russian-speaking operators for fifteen years. It does not prove TeamPCP is Russian-operated, but it adds another data point on top of the language signature in earlier waves. The attribution arc is converging on a Russian-speaking, financially-motivated operator with the technical chops to compromise OIDC trust paths and the patience to run a worm that pays out across multiple campaigns.
The Lesson Is Old, the Surface Is New
The lesson — never trust a package because it has historically been trustworthy — is older than npm. The surface is new: AI coding agent configurations, OIDC publish-token trust paths, repository CI secrets harvested by injected workflows. Defenders who do not extend their mental model to those surfaces will be the ones whose 11.6 MB self-replicator is committed back into their public repositories tomorrow morning.
The good news is the disclosure is fast — five research firms, simultaneous reports, a clear advisory within four hours of publish. The bad news is the worm has a four-hour head start and 1,100 confirmed victims.
Watch the IOCs. Audit the configs. Rotate the tokens. We will keep watching TeamPCP.
Her name was Renee Nicole Good.
His name was Alex Jeffery Pretti.
