Step Security Reports Shai-Hulud Worm in Hijacked Intercom npm Package, Targeting Cloud Credentials

Summary
Step Security reports [email protected] was published with a Shai-Hulud payload that runs through a new preinstall hook, targets GitHub/npm and AWS, GCP and Azure credentials, and uses private GitHub repositories for exfiltration and npm tokens to propagate.
Key points
- Step Security identifies [email protected], published April 30, 2026, as malicious and recommends version 7.0.3 as the safe version.
- The reported package adds a preinstall hook and obfuscated router_runtime.js payload; its unpacked size increased from about 6 MB to 17.8 MB, and SLSA provenance attestations are absent.
- The setup.mjs loader downloads Bun 1.3.13 to run the payload; the analysis also describes daemonization and temporary-file cleanup intended to hinder detection.
- The payload reportedly searches for GitHub and npm tokens, AWS, GCP and Azure credentials, private keys, and other secrets in files and environment variables.
- Step Security says the payload uses a stolen GitHub token to create a private repository for exfiltration and stolen npm tokens to propagate to packages the victim can publish.
- Attribution to Shai-Hulud/TeamPCP is based on shared tooling and behaviors, including the Bun version, obfuscation cipher, daemonization method, and OIDC publishing pattern.
- For affected installations, Step Security recommends downgrading, auditing CI/CD activity, rotating accessible credentials, and using install-script restrictions and exact version pins.
Article Details
- Attack Vectors
- The compromised [email protected] npm package runs a newly added preinstall hook, node setup.mjs, which downloads or reuses Bun and launches the obfuscated router_runtime.js payload.
- The payload harvests GitHub and npm tokens, cloud credentials from AWS and GCP metadata endpoints, Azure credentials, private keys, and other secrets from configuration files and environment variables.
- Using stolen GitHub credentials, the payload creates a private repository under the victim's account and commits encrypted harvested credentials and cloud metadata.
- Stolen npm publish tokens are used to enumerate packages the token can publish, inject the worm's files and preinstall hook, and publish compromised package versions.
- Defensive Notes
- Remove [email protected], install the reported safe version [email protected] with --ignore-scripts, and check for setup.mjs and router_runtime.js in installed packages.
- Rotate all secrets accessible to affected machines and CI/CD jobs, including GitHub and npm tokens, AWS credentials, GCP service account credentials, Azure secrets, and other environment secrets.
- Audit CI/CD runs that installed the compromised package, npm publishing activity, newly created private GitHub repositories, and cloud audit logs for unexpected credential use.
- Use npm ci --ignore-scripts as a CI/CD policy, pin exact dependency versions, and verify SLSA attestations for packages that support them.
- Use step-level egress controls to block undeclared outbound connections during install steps; the article identifies unexpected GitHub API and cloud metadata requests as useful signals.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| SHA1 | 1a1b1d0d89fadf7664c42ec628bac7d39a71bd50 | npm shasum for the compromised [email protected] package. |
| SHA256 | 5ae8b2343e97cc3b2c945ec34318b63f27fa2db1e3d8fbaa78c298aa63db52ed | SHA-256 of router_runtime.js, the obfuscated credential-stealing payload. |
| SHA256 | 5f748fbc89cde66abefa826439c765a0081a027792e9da8d80fbf23571311622 | Tarball SHA-256 for the compromised [email protected] package. |
| SHA256 | fe64699649591948d6f960705caac86fe99600bf76e3eae29b4517705a58f0e2 | SHA-256 of setup.mjs, the malicious package loader. |
| URL | hxxps[:]//api[.]github[.]com/user | GitHub API endpoint the payload uses with stolen credentials as part of exfiltration to a private repository under the victim's account. |
MITRE ATT&CK
T1005 · Data from Local SystemThe payload scans local configuration files and environment data to collect credentials and other secrets.T1027 · Obfuscated Files or Informationrouter_runtime.js is a single-line obfuscated JavaScript payload using a hex-indexed string array and a PBKDF2-backed cipher to decrypt strings at runtime.T1059.007 · JavaScriptThe package's preinstall hook runs setup.mjs, which launches the JavaScript payload using Bun.T1070.004 · File DeletionThe loader deletes the downloaded Bun archive and removes its temporary directory and Bun binary after execution.T1071.001 · Web ProtocolsThe payload communicates with the GitHub API over a web protocol as part of its reported exfiltration channel.T1105 · Ingress Tool TransferThe loader downloads and extracts a Bun runtime archive when Bun is not already installed.T1119 · Automated CollectionThe payload uses automated pattern matching to collect tokens, cloud credentials, private keys, and generic API keys from multiple sources.T1195.002 · Compromise Software Supply ChainThe report describes a compromised npm package and publishing pipeline distributing a malicious preinstall hook and payload.T1552.001 · Credentials In FilesThe payload scans configuration files and service account credential JSON files for secrets.T1552.004 · Private KeysThe payload searches for PEM-encoded RSA and ECDSA private keys.T1552.005 · Cloud Instance Metadata APIThe payload queries AWS and GCP metadata endpoints to obtain instance role credentials and service account tokens.T1567.001 · Exfiltration to Code RepositoryThe payload encrypts harvested credentials and cloud metadata and commits them to a private GitHub repository under the victim's account.
Threat Actors
Malware
Vendors
Amazon Web Servicesexpanded its collection scope from GitHub and npm tokens to a full multi-cloud credential sweep targeting AWS instance credentials (via the IMDS endpoint at 169.254.169.254), GCP service account tokens (viaGCPcredential sweep targeting AWS instance credentials (via the IMDS endpoint at 169.254.169.254), GCP service account tokens (via metadata.google.internal), Azure connection strings, private keys, and genericGitHubcompromised packages combined. The malicious version was published today at 14:41 UTC via a hijacked GitHub Actions OIDC publishing pipeline, confirming the worm is actively propagating through CI/CDIntercomand @cap-js/[email protected] were compromised by the Shai-Hulud worm, a third major npm package has fallen: [email protected], the official Node.js SDK for the Intercom customer messaging platform, with 361,510 weeklyMicrosoft Azure(via the IMDS endpoint at 169.254.169.254), GCP service account tokens (via metadata.google.internal), Azure connection strings, private keys, and generic API key patterns. The same __decodeScrambled PBKDF2 ciphernpmhours after [email protected] and @cap-js/[email protected] were compromised by the Shai-Hulud worm, a third major npm package has fallen: [email protected], the official Node.js SDK for the Intercom customer messagingStepSecurityDisclosure: StepSecurity has filed a GitHub issue notifying the Intercom team of this compromise: github.com/intercom/intercom-node/issues/518.Vercelif (process.env.VERCEL || process.env.NOW_GITHUB_DEPLOYMENT) // Vercel deployments
Products
AWSexpanded its collection scope from GitHub and npm tokens to a full multi-cloud credential sweep targeting AWS instance credentials (via the IMDS endpoint at 169.254.169.254), GCP service account tokens (viaAzure(via the IMDS endpoint at 169.254.169.254), GCP service account tokens (via metadata.google.internal), Azure connection strings, private keys, and generic API key patterns. The same __decodeScrambled PBKDF2 cipherGCPcredential sweep targeting AWS instance credentials (via the IMDS endpoint at 169.254.169.254), GCP service account tokens (via metadata.google.internal), Azure connection strings, private keys, and genericGitHubcompromised packages combined. The malicious version was published today at 14:41 UTC via a hijacked GitHub Actions OIDC publishing pipeline, confirming the worm is actively propagating through CI/CDGitHub Actionscompromised packages combined. The malicious version was published today at 14:41 UTC via a hijacked GitHub Actions OIDC publishing pipeline, confirming the worm is actively propagating through CI/CD infrastructureintercom-client@cap-js/[email protected] were compromised by the Shai-Hulud worm, a third major npm package has fallen: [email protected], the official Node.js SDK for the Intercom customer messaging platform, with 361,510 weeklyNode.jsby the Shai-Hulud worm, a third major npm package has fallen: [email protected], the official Node.js SDK for the Intercom customer messaging platform, with 361,510 weekly downloads — more than the twonpmhours after [email protected] and @cap-js/[email protected] were compromised by the Shai-Hulud worm, a third major npm package has fallen: [email protected], the official Node.js SDK for the Intercom customer messagingVercelif (process.env.VERCEL || process.env.NOW_GITHUB_DEPLOYMENT) // Vercel deployments
Tools
AI Package AnalystStepSecurity’s AI Package Analyst monitors every new npm publish in real time, diffing each release against the full version history. For [email protected], four signals triggered an immediate CRITICAL verdictBunThe package carries the same preinstall: node setup.mjs hook and Bun-staged loader found in every prior Shai-Hulud payload, but the credential stealer has undergone a significant evolution: the payload — now disguisedHarden Runnerappear in every CI/CD environment’s default allowlist. The only network-layer defense that works is Harden Runner’s step-level egress lockdown, which blocks unexpected api.github.com API calls during install steps
