Significant cyber incident

Shai-Hulud npm worm

In mid-September 2025, a self-copying worm called Shai-Hulud spread through the npm package registry, the main store for JavaScript code.

In short

In mid-September 2025, a self-copying worm called Shai-Hulud spread through the npm package registry, the main store for JavaScript code. It took over maintainer accounts, added malicious install scripts to their packages, and stole GitHub, npm and cloud credentials, which were then used to publish more infected packages. GitHub removed more than 500 packages, and CISA warned of a second, more destructive wave in November 2025.

What happened

GitHub said it was notified of the Shai-Hulud attack on 14 September 2025. The worm entered npm through compromised maintainer accounts and added malicious post-install scripts to popular JavaScript packages. CISA published an alert on 23 September 2025 and said more than 500 packages were compromised.

The malware searched for credentials, including GitHub tokens and cloud keys. It sent them to an endpoint the actor controlled and also placed them in a public GitHub repository named Shai-Hulud. It then used stolen npm access to publish more infected package versions. GitHub removed more than 500 packages and blocked new uploads that carried the malware’s known indicators.

On 25 November 2025 the New Zealand NCSC reported an evolved version of the worm that compromised almost 500 packages. GitHub later called this second wave Shai-Hulud 2.0.

Timeline

  1. 2025-09-14

    GitHub says it was notified of the Shai-Hulud attack.

  2. Before 2025-09-16

    CISA later advises pinning npm dependencies to releases from before this date (14 September is when GitHub says it was notified).

  3. 2025-09-22

    GitHub publishes its plan for a more secure npm supply chain and says it removed 500+ compromised packages.

  4. 2025-09-23

    CISA publishes its alert and says the worm compromised over 500 packages.

  5. 2025-09-29

    New Zealand NCSC publishes an alert on the first wave. GitHub publishes the first phase of its npm security changes.

  6. Mid-October 2025

    New write-enabled granular tokens get a seven day default and 90 day maximum lifetime, according to GitHub's 29 September notice.

  7. 2025-11-05

    New npm classic tokens can no longer be created. New write tokens enforce 2FA by default.

  8. 2025-11-19

    Date GitHub gave for the end of existing classic tokens.

  9. 2025-11-25

    New Zealand NCSC reports an evolved version of the worm compromising almost 500 packages.

  10. 2025-12-09

    GitHub says all npm classic tokens are permanently revoked and npm login now gives two-hour session tokens.

  11. 2025-12-23

    GitHub publishes a post describing the multi-wave campaign and its next npm security steps.

How the attack worked

Getting in

GitHub said the worm entered npm through compromised maintainer accounts. After initial access, CISA said the malware scanned the environment for credentials. It targeted GitHub personal access tokens and API keys for AWS, GCP and Azure. The sources opened do not say how the first accounts were compromised.

Stealing and spreading

CISA said the malware sent the credentials to an actor-controlled endpoint and uploaded them to a public repository named Shai-Hulud. It then logged in to npm as the compromised developer, injected code into other packages and published the infected versions. GitHub said the code was a malicious post-install script, so it ran when someone installed the package.

GitHub also warned that an attacker can keep stolen tokens and start a new campaign weeks or months later.

The second wave

GitHub said Shai-Hulud 2.0 added credential exposure across victims, command and control through self-hosted runner registration, destructive functions and a focus on CI environments. It used a multi-stage payload and changed package version numbers so infected releases looked like normal updates.

The New Zealand NCSC said this variant installed the Bun runtime with setup_bun.js, ran bun_environment.js, and used a randomly named repository for stolen data. If it could not authenticate to GitHub or find an npm token, it wiped files in the user’s home directory.

No source opened for this page maps the incident to MITRE ATT&CK technique ids, so none are listed.

Who says who was behind it

No public attribution for the September 2025 first wave or the November 2025 second wave in the government and GitHub sources opened for this page. CISA calls the actor a "malicious cyber actor" and does not name a group.
Attributed by CERT-EU, 2 June 2026: its May 2026 brief names TeamPCP as the actor behind a supply-chain attack dubbed Shai-Hulud in May 2026 (over 160 npm and PyPI packages). That brief does not tie TeamPCP to the 2025 waves, so treat it as a later and separate claim.

Impact

CISA said the first wave compromised over 500 packages. GitHub said it removed 500+ compromised packages. The New Zealand NCSC said the second wave compromised almost 500 packages. No opened source gives a count of downstream victims, stolen credentials or financial loss.
GitHub said the worm could have enabled an endless stream of attacks without timely action. The New Zealand NCSC said the second wave could wipe the home directory of an affected user in some conditions.

Government and regulator response

  • By 22 September 2025: GitHub removed 500+ compromised packages and blocked uploads of new packages containing the malware’s indicators.
  • 22 September 2025: GitHub announced a plan to limit publishing to 2FA local publishing, short-lived granular tokens and trusted publishing, and to retire classic tokens.
  • 23 September 2025: CISA advised a dependency review, pinning to versions from before 16 September 2025, rotating developer credentials, phishing-resistant MFA, and blocking webhook.site.
  • 29 September 2025: the New Zealand NCSC published similar advice for the first wave.
  • 5 November 2025: GitHub stopped new classic tokens and enforced 2FA on new write tokens, with a 90 day cap on existing write tokens.
  • 25 November 2025: the New Zealand NCSC advised scanning endpoints, rotating GitHub, npm, cloud and CI/CD credentials, disabling postinstall scripts in CI and freezing package updates.
  • 9 December 2025: GitHub permanently revoked classic tokens, moved npm login to two-hour sessions and made 2FA default for new packages.
  • 23 December 2025: GitHub listed bulk OIDC onboarding, more OIDC providers and staged publishing as next steps.

Lessons

  1. One stolen token can reach many packages

    The worm used a maintainer's own npm access to publish into other packages, so one account fed the next.

  2. Install scripts run before anyone reviews them

    The malicious code ran as a post-install script, so installing a package was enough to run it.

  3. Long-lived tokens are the weak point

    GitHub moved to short-lived tokens, 2FA by default and revoked classic tokens after the incident.

  4. Stolen secrets can be used later

    GitHub warned attackers can hold tokens and attack weeks or months afterwards, so rotation matters after any scare.

  5. Attackers adapt quickly

    GitHub said the second wave changed tactics and had a harder-to-detect payload, so fixing only the last variant is not enough.

  6. Phishing-resistant MFA and trusted publishing help

    CISA and GitHub both recommend them for developer accounts and for publishing.

What to check in your own organization

  1. Search lock files for affected packages

    Check package-lock.json and yarn.lock, including nested dependencies, against the published lists of compromised packages.

  2. Look at versions published after mid-September 2025

    CISA advised pinning to releases from before 16 September 2025.

  3. Rotate developer and CI credentials

    Rotate GitHub, npm, cloud and CI/CD credentials if a bad package was installed anywhere.

  4. Check GitHub for stray repositories and branches

    Look for unexpected repositories, such as one named Shai-Hulud or a random name, and unexpected branches.

  5. Review install scripts in CI

    Consider disabling npm postinstall scripts in CI where possible and freeze updates during an incident.

  6. Enforce phishing-resistant MFA and expiring tokens

    Check that GitHub and npm accounts use it and that tokens have an expiry date.

  7. Watch outbound traffic

    Block webhook.site and review firewall logs for suspicious domains, as CISA advised.

Questions

What was Shai-Hulud?

A self-replicating worm in the npm registry. CISA said it compromised over 500 packages.

How did it spread?

It stole credentials, logged in to npm as the compromised developer, injected code into other packages and published infected versions.

What did it steal?

CISA said GitHub personal access tokens and API keys for AWS, GCP and Azure.

Was there a second wave?

Yes. The New Zealand NCSC reported an evolved version on 25 November 2025, and GitHub called it Shai-Hulud 2.0.

What did GitHub change afterwards?

It stopped new classic tokens, revoked existing ones, capped token lifetimes, enforced 2FA on new write tokens and added two-hour login sessions.

Who is behind it?

No public attribution in the 2025 sources opened. CERT-EU named TeamPCP in a 2026 brief about a later attack with the same name, not the 2025 waves.

In our research

  1. Technology and SaaS Industry
  2. Malicious package Glossary term

Sources

  1. Widespread Supply Chain Compromise Impacting npm Ecosystem CISA
  2. Our plan for a more secure npm supply chain GitHub Blog
  3. Strengthening npm security: Important changes to authentication and token management GitHub Changelog
  4. npm security update: Classic token creation disabled and granular token changes GitHub Changelog
  5. npm classic tokens revoked, session-based auth and CLI token management now available GitHub Changelog
  6. Strengthening supply chain security: Preparing for the next malware campaign GitHub Blog
  7. Widespread supply chain compromise impacting npm ecosystem NCSC New Zealand
  8. New wave of widespread supply chain compromise impacting npm ecosystem NCSC New Zealand
  9. Securing the open source supply chain across GitHub GitHub Blog
  10. CERT-EU Cyber Brief 26-06, May 2026 CERT-EU