Mini Shai-Hulud npm Worm Spreads to 444 Packages, Stealing Developer Credentials

Summary
A Mini Shai-Hulud npm worm has spread to at least 444 packages, stealing developer and CI credentials, exfiltrating data, and using compromised accounts to poison packages and repositories.
Key points
- The worm starts through an npm preinstall script that launches an obfuscated JavaScript payload using Bun.
- It searches developer machines and CI runners for credentials, configuration files, and secrets across services including GitHub, npm, AWS, Kubernetes, and Vault.
- Stolen data is sent to attacker-controlled infrastructure or stored in public GitHub repositories created as dead drops.
- The worm uses stolen credentials and GitHub Actions OIDC access to publish poisoned npm packages and inject malicious workflows or repository files.
- Its command server can return JavaScript that the payload evaluates on the infected system, enabling remote code execution.
- The article advises isolating affected hosts, preserving logs, rebuilding CI runners, revoking sessions, rotating exposed credentials, and checking GitHub and npm activity.
Article Details
- Attack Vectors
- A malicious npm package runs a preinstall script that launches setup.mjs and the JavaScript payload using Bun.
- Stolen credentials are used to publish poisoned npm package releases, inject GitHub Actions workflows, and commit malicious files across repository branches.
- The payload collects developer and CI credentials, exfiltrates them to a resolved C2 destination or public GitHub repositories, and evaluates JavaScript returned by the C2 server.
- The worm can install GitHub-token-monitor persistence and target developer environments through malicious .vscode tasks and .claude configuration.
- Defensive Notes
- Isolate affected workstations and CI runners, preserve relevant logs, and rebuild disposable runners from trusted images.
- Revoke active sessions and rotate credentials available to the affected process from a known-clean system.
- Review GitHub for unexpected public repositories containing results/, suspicious repository descriptions, unexpected branch commits, workflow changes, OIDC requests, and repository-creation or contents/results/ API activity.
- Review npm packages controlled by affected maintainers for unexpected patch releases, a new @opensearch/setup optional dependency, unfamiliar publishing activity, OIDC exchanges, and provenance or trusted-publishing changes.
- Detection should focus on the /router path, npm/Bun process ancestry, credential-access behavior, unusual GitHub repository creation, and subsequent package publication rather than relying only on domain blocklists.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| DOMAIN | npm-cache[.]com | Attacker-controlled domain resolved by the malware for data exfiltration. |
| IPV4 | 169[.]254[.]169[.]254 | Cloud metadata endpoint queried by the malware to obtain workload credentials. |
| IPV4 | 169[.]254[.]170[.]2 | Cloud workload-credential endpoint queried by the malware. |
| SHA256 | 9fc2570b7cef51c1b8df116d144d11ff4096357be7d2c4c6367cfc2509cf1bcc | SHA-256 hash of the malicious math_init.js and Math_Symbol.js payloads. |
| SHA256 | fd3ca4007b225fdf8de7af4345a19179d5efa8c4bb9205f88cda806e5684b1eb | SHA-256 hash of the malicious setup.mjs dropper. |
| URL | hxxps[:]//npm-cache[.]com/router | Malicious exfiltration endpoint used by the malware. |
MITRE ATT&CK
T1053.005 · Scheduled TaskThe payload installs persistence using a Linux systemd-style gh-token-monitor.service.T1059.007 · JavaScriptThe malware executes JavaScript through Bun and evaluates JavaScript returned by its command server.T1195.002 · Compromise Software Supply ChainThe worm publishes poisoned npm package releases by adding an attacker-controlled optional dependency.T1528 · Steal Application Access TokenThe worm collects and validates GitHub and npm tokens and uses stolen credentials to access accounts and propagate.T1543.001 · Launch AgentThe payload installs a macOS LaunchAgent named com.user.gh-token-monitor.T1552.001 · Credentials In FilesThe payload searches filesystem locations including .env files for credentials and secrets.T1552.005 · Cloud Instance Metadata APIThe malware queries cloud instance and task metadata endpoints for workload credentials.T1555 · Credentials from Password StoresThe payload searches local configuration files and credential stores for developer, cloud, and application credentials.T1567.002 · Exfiltration to Cloud StorageThe malware exfiltrates stolen data by creating public GitHub repositories and uploading files under results/.
People
Malware
Vendors
GitHubsame with the same file hash). It searches developer machines and CI runners for credentials including GitHub, npm, AWS, Kubernetes, Vault, Azure, Google Cloud, Terraform, Docker, Slack, and others. It exfiltratesnpmToday an unknown threat actor released a new npm worm that started in the keyv and cachable ecosystems and has since expanded into at least 444 packages, publishing over 2000 malicious versions. One of the biggest hit
Products
AWS Secrets Managerkeys, secret keys, and session tokens. With working credentials it enumerates regions and queries AWS Secrets Manager using operations equivalent to ListSecrets and GetSecretValue.BunInitial execution: An npm preinstall script launches setup.mjs, which runs the payload with BunGitHub ActionsAffected ecosystem: npm, GitHub, GitHub Actions, developer workstations, and CI/CD runnersKubernetesfile hash). It searches developer machines and CI runners for credentials including GitHub, npm, AWS, Kubernetes, Vault, Azure, Google Cloud, Terraform, Docker, Slack, and others. It exfiltrates what it finds,VaultIt searches developer machines and CI runners for credentials including GitHub, npm, AWS, Kubernetes, Vault, Azure, Google Cloud, Terraform, Docker, Slack, and others. It exfiltrates what it finds, creates public