TL;DR
- Shai-Hulud 2.0 was a self-replicating npm supply-chain worm that activated during
npm installornpm publish. - Approximately 25,000 repositories compromised; credentials from more than 1,000 organisations exfiltrated to attacker-controlled infrastructure (Entro Security).
- Innovated on v1 (September 2025) by introducing a dead-man's-switch that would expose victim secrets publicly if the maintainer attempted certain types of cleanup.
- Root NHI causes: NHI2 (Secret leakage) via environment-variable harvesting, and NHI3 (Vulnerable third-party NHI) via compromised maintainer credentials on upstream packages.
- The event drove npm to accelerate trusted-publishing (OIDC-based publishing), enhanced 2FA requirements, and increased post-publish scanning.
Summary
Shai-Hulud 2.0 was a propagating npm package worm that executed during package installation and publishing, performing two primary functions: (1) harvesting secrets from the local environment (environment variables, common secret file locations, CI/CD variables, cloud-credential files), and (2) if the infected environment had npm publish permissions, propagating itself to other packages owned by the same publisher.
The worm is named for the sandworms from Dune, a reference the attacker embedded in package-name manipulations and code comments. Version 1.0 appeared in September 2025 and affected a smaller scope. Version 2.0, observed in mid-November 2025, was substantially more sophisticated and compromised the ecosystem at a scale not previously seen.
Several independent research teams, including Socket, Aikido, StepSecurity, and GitGuardian, contributed to the public forensic record. npm responded with accelerated security feature rollouts.
Background: Shai-Hulud v1 (September 2025)
The first Shai-Hulud wave in September 2025 compromised several hundred packages through a similar pattern: credential theft followed by propagation through packages the compromised credentials could publish to. It established the technique but at a limited scale, and npm's response included immediate 2FA uplift and publisher account recovery processes.
The v1 wave was contained within weeks. Version 2.0's authors had clearly studied v1's weaknesses.
Timeline (reconstructed from public reporting)
| Date | Event |
|---|---|
| Early Nov 2025 | First infected packages published to npm. Multiple initial-access paths: compromised maintainer credentials, compromised CI tokens with publish rights, phishing-harvested npm tokens. |
| Mid Nov 2025 | Worm propagates via maintainer-owned package chains. Installations at downstream consumers begin harvesting secrets. |
| Mid to late Nov 2025 | Security researchers (Socket, StepSecurity, Aikido, GitGuardian, others) detect anomalous post-install behaviour in the ecosystem. npm begins mass takedowns. |
| Late Nov 2025 | npm publishes incident advisories. Major maintainer accounts are forcibly re-authenticated and tokens revoked. Dead-man's-switch behaviour observed in some cleanup attempts. |
| Dec 2025 to Jan 2026 | Aggregate-impact estimates firm up. npm announces trusted-publishing (OIDC) as a preferred path forward. Enterprise victim disclosures accumulate. |
| Q1 2026 | Ongoing remediation at consumer organisations. Secret-rotation campaigns across thousands of environments. |
How the worm worked
On a compromised-package installation or publish event, the worm executed via postinstall scripts and lifecycle hooks to perform the following:
- Environment harvest. Read
process.envand filter for secret-like patterns (AWS keys, GitHub tokens, npm tokens, cloud-credential environment variables, generic API-key patterns). Collect values. - Filesystem harvest. Read common secret-file locations:
~/.aws/credentials,~/.npmrc,~/.docker/config.json, GitHub CLI config, kubeconfig files,.envfiles in common project locations. - CI-context harvest. In GitHub Actions / GitLab CI / Codecov contexts, extract pipeline-specific secrets accessible to the running job.
- Exfiltration. Send harvested material to attacker-controlled infrastructure, in some observed variants, to public-by-design destinations including GitHub repositories created under the victim's own credentials.
- Propagation. If npm publish credentials were available in the compromised environment, identify packages the compromised maintainer could publish to and publish new infected versions of them.
- Dead-man's-switch (v2 innovation). Install a conditional-activation component (see next section).
The dead-man's-switch
Shai-Hulud 2.0's most novel feature: in certain variants, the worm installed a dormant component that monitored for cleanup behaviour (package unpublishes, repository deletions, credential rotations) and, if triggered, would exfiltrate the previously-harvested secrets to a public destination, making them discoverable by any search.
The effect was psychological as much as technical. Maintainers who might otherwise have aggressively cleansed their accounts were put in a position where cleanup itself might expose their users further. In several documented cases, maintainers paused cleanup while coordinating with npm and incident responders to characterise the dead-man's-switch behaviour in their specific infected packages before remediation.
The technique substantially extended the window in which harvested secrets remained useful to the attacker and increased the coordination burden on the ecosystem's defenders.
NHI root cause analysis
- NHI2, Secret leakage. The central failure: secrets held as environment variables or in well-known file locations on developer and CI machines became the attacker's target. Every credential harvested was a credential that was readable by a child process in an environment that had executed an untrusted package.
- NHI3, Vulnerable third-party NHI. The initial-access vector included compromised npm maintainer accounts. Each infected package is an NHI (its publisher's credential on npm) that had been compromised.
- NHI7, Long-lived secrets. Harvested secrets were valuable to the attacker precisely because they persisted. A short-lived ephemeral token would have had limited post-harvest value.
- NHI8, Environment isolation. Many infected CI environments had credentials accessible to pipeline jobs that should have been confined to narrower scopes. Broad environment-level availability of secrets amplified harvest volume.
Impact
- Approximately 25,000 repositories compromised, a mix of open-source public projects and private repositories that used the infected packages.
- Credentials from more than 1,000 organisations (Entro Security; ~1,195) harvested in aggregate. Distribution skews toward AWS/GCP/Azure credentials, npm tokens, GitHub tokens, database passwords, and generic API keys.
- Thousands of enterprise organisations conducted mass credential-rotation campaigns in Q4 2025 and Q1 2026.
- Substantial npm-ecosystem trust impact; accelerated adoption of trusted-publishing (OIDC) patterns and 2FA.
- Multiple follow-on incidents where harvested credentials were used for downstream breaches. Attribution of those secondary incidents to Shai-Hulud 2.0 is often difficult, since the harvested credentials were commoditised.
- Regulatory notifications in multiple jurisdictions given the scale of PII-adjacent exposures.
Mitigation playbook for affected organisations
- Determine exposure. Audit package.json and lockfiles across all repositories, CI configurations, and developer machines. Check against the published Shai-Hulud 2.0 IOC lists maintained by security research teams.
- Rotate all potentially-exposed credentials. Any credential that was available as an environment variable or in a common file location on an affected endpoint during the exposure window is candidate-compromised. Rotate broadly, not selectively.
- Revoke npm tokens and re-issue via trusted publishing. Where packages are published, move to OIDC-based trusted publishing, which eliminates long-lived publish tokens.
- Re-evaluate CI secret scopes. Pipelines should receive only the secrets they operationally need, not a broad environment of everything. Use CI-native secret scoping where available.
- Improve developer-machine hygiene. Credentials should live in platform-native keychains, not plaintext
.envfiles or shell profiles. Enterprise endpoints should have EDR that detects the kind of environment-scraping the worm used. - Check for dead-man's-switch artefacts. Before unpublishing or deleting infected packages, consult the current security-research guidance for the specific worm variant that affected you.
- Notify downstream. If you were a publisher whose package was infected, communicate clearly with your consumers about the window of exposure and the specific actions they should take.
Lessons that transfer
- Static credentials in CI are a worm attractor. The economics of secret-harvesting supply-chain attacks depends on the abundance of long-lived credentials in CI environments. Organisations that have moved to OIDC federation and workload identity federation for their CI had smaller harvests.
- Package-publish credentials are production-grade NHIs. Treat npm tokens, PyPI tokens, Maven credentials, and similar publisher credentials as production-grade secrets with appropriate rotation, 2FA, and scope controls.
- Trusted publishing reduces supply-chain risk asymmetrically. OIDC-based publishing via GitHub Actions (or equivalents) eliminates long-lived publisher tokens entirely. This is the structural fix for the Shai-Hulud class of attack.
- Post-install scripts are a meaningful attack surface.
npm installexecutes code. Consumer organisations with the means should consider restricting or auditing post-install behaviour, especially in CI. - Dead-man's-switches are now part of the threat landscape. Incident response must account for the possibility that cleanup actions themselves trigger further harm. Coordination with researchers and platform operators matters.
- The ecosystem's response has to be structural, not reactive. Each new worm wave surfaces the same underlying issue, too many credentials, in too many places, with too-long lifetimes. The long-term fix is ambient NHI hygiene, not post-incident cleanup.
Frequently asked questions
What was the Shai-Hulud npm worm?
A self-replicating attack against the npm ecosystem in which compromised packages harvested developer and CI credentials, then used those stolen credentials to publish further compromised packages. The self-propagation is what distinguishes it: each successful credential theft expanded the attack surface without further attacker action.
Why does self-replication change the risk calculation?
Because containment time becomes the dominant variable rather than initial blast radius. A conventional supply-chain compromise affects the packages the attacker could reach; a self-replicating one grows at a rate set by how many maintainer credentials it captures. Credential lifetime therefore has outsized effect, since every expired token is a branch of propagation that terminates.
What protects a package registry account from this pattern?
Publishing credentials that are short-lived and scoped to a single package, hardware-backed multi-factor authentication on maintainer accounts, provenance attestation so consumers can verify build origin, and automated publishing from a controlled pipeline rather than from developer machines. The last removes the class of credential the worm was harvesting.
What should a consuming organisation do?
Pin dependencies and review changes rather than accepting floating versions, restrict what build-time scripts may do, and ensure CI credentials are short-lived and narrowly scoped so that a compromised package in your pipeline captures little of value. Detection after the fact matters less than reducing what is available to steal.
Would this credential have been in your inventory?
Every breach on this page began with a non-human identity nobody was tracking. HumanAudit runs independent NHI baseline assessments that produce a measured inventory, an ownership map, and a tested revocation time.