Mini Shai-Hulud Worm Reuses VS Code Task Execution Technique in SAP CAP npm Attack

Summary
Mini Shai-Hulud spread through four SAP CAP npm packages, using VS Code tasks and Claude Code hooks to execute payloads and propagate across repositories. The article details its links to PolinRider and recommends hunting and credential rotation.
Key points
- The article says Mini Shai-Hulud’s first wave reached more than 1,000 repositories and identifies four affected SAP CAP packages and malicious versions: mbt 1.2.48, @cap-js/sqlite 2.2.2, @cap-js/postgres 2.2.2, and @cap-js/db-service 2.10.1.
- The worm adds a .vscode/tasks.json task that runs when a workspace folder opens, reusing a technique associated with PolinRider and TasksJacker.
- It also installs a Claude Code SessionStart hook and uses Bun to run an obfuscated payload, which the article says may evade detections focused on Node.js.
- The article reports that the mbt package used a stolen npm token, while the three @cap-js packages were published through OIDC trust configured for an entire repository.
- Attribution remains unsettled: vendors attribute the campaign to TeamPCP, while the article says whether it is the original Shai-Hulud crew, a successor, or a copycat is unknown.
- Recommended actions include hunting for unrecognized folderOpen tasks and Claude Code hooks, auditing affected package use, rotating credentials accessible to affected hosts, and narrowing OIDC trust to protected workflows.
Article Details
- Attack Vectors
- Malicious npm package releases spread Mini Shai-Hulud; the mbt package was published using a stolen npm token, while three @cap-js packages used OIDC trusted publishing with an overly broad repository trust configuration.
- The worm writes .vscode/tasks.json configured with "runOn": "folderOpen" into accessible repositories and branches, causing its task to execute when a developer opens a trusted workspace in VS Code.
- The payload adds a .claude/settings.json SessionStart hook and .claude/execution.js to trigger execution when Claude Code attaches to a workspace.
- A preinstall loader downloads Bun v1.3.13 from an official GitHub release, runs an obfuscated execution.js, and deletes the downloaded binary afterward.
- The worm harvests accessible cloud and developer credentials and creates public, Dune-themed repositories on victims’ own GitHub accounts as exfiltration dead-drops.
- Defensive Notes
- Hunt across repositories for unrecognized .vscode/tasks.json files containing "runOn": "folderOpen", Claude Code SessionStart hooks, and .claude/execution.js.
- Investigate unrecognized .github/workflows/format-check.yml files and branches named dependabout/github_actions/format/setup-formatter.
- Search for the listed setup.mjs and execution.js SHA-256 hashes, and for PolinRider signatures "rmcej%otb%",2857687, temp_auto_push.bat, and config.bat.
- Audit the affected CAP packages and build or developer hosts that installed them on or after April 29; the article advises treating reachable credentials as compromised and rotating them.
- Require review for changes to .claude/, .vscode/, .cursor/, and .continue/ configuration; allowlist SessionStart hooks and folderOpen tasks, and consider disabling VS Code workspace trust by default.
- Lock CAP dependencies below the malicious versions and scope GitHub Actions OIDC trust to a specific workflow on a protected branch.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| SHA256 | 4066781fa830224c8bbcc3aa005a396657f9c8f9016f9a64ad44a9d7f5f45e34 | SHA-256 of the Mini Shai-Hulud setup.mjs loader; the article identifies it as byte-for-byte identical across all four malicious packages. |
| SHA256 | 6f933d00b7d05678eb43c90963a80b8947c4ae6830182f89df31da9f568fea95 | SHA-256 of execution.js shipped with the malicious @cap-js/sqlite@2.2.2 package. |
| SHA256 | 80a3d2877813968ef847ae73b5eeeb70b9435254e74d7f07d8cf4057f0a710ac | SHA-256 of execution.js shipped with the malicious mbt@1.2.48 package. |
| URL | hxxps[:]//github[.]com/search?q=%22A+Mini+Shai-Hulud+has+Appeared%22&type=repositories | Article-identified search URL for finding the Dune-themed public GitHub repositories the worm creates as exfiltration dead-drops. |
MITRE ATT&CK
T1059.007 · JavaScriptThe malicious npm preinstall loader setup.mjs runs the payload under Bun.T1098.004 · SSH Authorized KeysThe worm writes its task file into branches across repositories accessible through the victim’s GitHub account, propagating its execution mechanism.T1195.002 · Compromise Software Supply ChainThe worm spread through malicious releases of npm packages in the SAP CAP ecosystem.T1546 · Event Triggered ExecutionThe payload configures a Claude Code SessionStart hook to call .claude/execution.js when the assistant attaches to a workspace.T1546.016 · Installer PackagesThe malware writes VS Code tasks.json with runOn set to folderOpen to execute when a repository is opened.T1552 · Unsecured CredentialsThe worm harvests credentials accessible from the infected developer machine or runner, including cloud and developer credentials.T1567.001 · Exfiltration to Code RepositoryThe worm creates public repositories on victims’ GitHub accounts as repositories for exfiltrated data.
Threat Actors
DeadCatx3Named in the article as another tracking name for TeamPCP.Lazarus GroupThe article attributes the earlier PolinRider/TasksJacker tradecraft to a DPRK-aligned campaign associated with Lazarus Group.PCPcatNamed in the article as another tracking name for TeamPCP.ShellForceNamed in the article as another tracking name for TeamPCP.TeamPCPThe article attributes the Mini Shai-Hulud / SAP CAP wave to TeamPCP; it says whether this group is the original Shai-Hulud crew, a successor, or a copycat remains unsettled.
Malware
ChainDropMini Shai-Hulud is a malicious npm worm by TeamPCP that spread to more than 1,000 repositories in its first wave. Vendor writeups have been calling its core trick “novel.” It isn’t. It’s a direct lift from thePolinRiderwave. Vendor writeups have been calling its core trick “novel.” It isn’t. It’s a direct lift from the PolinRider and TasksJacker playbook that Lazarus Group has been running on developer machines since late 2025. IfTasksJackerhave been calling its core trick “novel.” It isn’t. It’s a direct lift from the PolinRider and TasksJacker playbook that Lazarus Group has been running on developer machines since late 2025. If you’ve already
Products
Bun2. Bun runtime, not Node. The preinstall loader (setup.mjs) downloads Bun v1.3.13 from the official oven-sh/bun GitHub release and runs an 11.6 MB obfuscated execution.js under the Bun process, deleting the binaryClaude Code1. Claude Code SessionStart hook. Alongside tasks.json, the payload drops a .claude/settings.json configuring a SessionStart hook that fires when Claude Code attaches to the workspace, plus a .claude/execution.js fornpmMini Shai-Hulud is a malicious npm worm by TeamPCP that spread to more than 1,000 repositories in its first wave. Vendor writeups have been calling its core trick “novel.” It isn’t. It’s a direct lift from theSAP CAPPolinRider is attributed to a DPRK-aligned actor. The Mini Shai-Hulud / SAP CAP wave is being attributed across vendors to TeamPCP (also tracked as DeadCatx3, PCPcat, ShellForce) — the same group claimed theVS CodeVS Code’s tasks.json is a legitimate, well-documented feature for defining build, test, and lint tasks inside a workspace. The runOptions block lets a task auto-execute on certain triggers, and folderOpen is exactly