Join our Newsletter — 33% off our NHI Course
Home› Guides› Shai-Hulud npm Worm Guide: Waves, Token Theft and…
Guide Attack Techniques & Malware

Shai-Hulud npm Worm Guide: Waves, Token Theft and How to Contain It

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 12 min read
On this page

Shai-Hulud showed that a single stolen npm publishing token is enough to start a worm: each infected install harvests more tokens, and each token republishes more packages. Across waves in September 2025, November 2025 and the 2026 Mini Shai-Hulud campaign, the malware stole GitHub, npm and cloud credentials from developer laptops and CI runners and used them to spread. This guide profiles the worm family: names and waves, who is behind the later variant, techniques mapped to MITRE ATT&CK v20, how it abuses non-human credentials, and the detection and containment steps that work. It is written for platform, AppSec, DevOps and identity teams; it goes deeper than the Malicious Package and Dependency Confusion Guide, which covers package threats in general.

Key takeaways

  • The worm spreads on identities, not exploits. Shai-Hulud authenticates to npm as the victim with a stolen token and republishes the victim's other packages, so every compromised maintainer becomes a new source.
  • Install time is execution time. The first wave used a postinstall script; the second moved to preinstall with a fake Bun installer, so simply installing a dependency ran the payload on laptops and CI runners.
  • CI runners are the richest target. Runners hold publishing tokens, cloud keys and OIDC identities, and Mini Shai-Hulud read runner memory to recover short-lived tokens and publish through trusted publishing.
  • Containment means rotating everything reachable. CISA's advice was to rotate all developer credentials, not only npm tokens, and to check for new repositories, workflows and self-hosted runners created by the worm.
  • Trusted publishing helps but is not the end state. Removing stored tokens closes the first-wave path; tightly scoped OIDC, disabled install scripts in CI and release approval close the later ones.

Who they are (names and aliases)

Shai-Hulud is malware, not a named group. MITRE ATT&CK tracks the original worm as software S9008, first reported in September 2025, and the derivative Mini Shai-Hulud as S9043, which it attributes to the group TeamPCP (G1056). No public source has attributed the 2025 waves to a named actor.

Name or IDPeriodWhat it refers to
Shai-Hulud (S9008), first waveFrom 15 September 2025Postinstall worm; widely reported starting with @ctrl/tinycolor; GitHub removed more than 500 packages
Sha1-Hulud: The Second Coming, also called Shai-Hulud 2.0From 24 November 2025Preinstall variant with setup_bun.js and bun_environment.js; exfiltration repositories carry that description
Mini Shai-Hulud (S9043)2026, including SAP packages on 29 April 2026Derived credential stealer and worm used by TeamPCP; targets CI workflows, OIDC tokens and AI tool configuration
TeamPCP (G1056)2026Group ATT&CK links to Mini Shai-Hulud. See the TeamPCP Threat Actor Profile Guide

Copycat worms reuse the code and the name. Treat the label in a report as a starting point and check indicators before assuming a known variant.

Targeting and motivation

  • Who is hit: package maintainers and anyone who installs their packages. The worm's victims are defined by the dependency graph, not by sector.
  • What it wants: credentials. CISA lists GitHub personal access tokens and API keys for AWS, Google Cloud and Microsoft Azure; ATT&CK adds .npmrc tokens, environment variables, cloud instance metadata and secrets from AWS Secrets Manager, Google Cloud Secret Manager and Azure Key Vault.
  • Why publishing tokens matter most: a publishing token is both loot and the propagation mechanism. Every token with publish rights to popular packages multiplies reach.
  • Destruction as leverage: the second wave tried to overwrite and delete the user's home directory if it could not steal credentials or exfiltrate; Mini Shai-Hulud carries a wiper that ATT&CK says fires only under specific location conditions, including Iran and Israel, behind a random one-in-six gate.
  • AI tooling: Mini Shai-Hulud modified AI coding agent configuration files to create execution hooks. See the AI IDE and Coding Agent Security Guide.

Tactics and techniques (MITRE ATT&CK)

IDs are ATT&CK v20 relationships recorded against S9008 and S9043.

TacticTechniqueBehaviourPrimary defence
Initial accessT1195.001 Compromise Software Dependencies and Development ToolsTrojanised package versions published from compromised maintainer accountsRelease cooldown before adopting new versions; lockfiles
Persistence and executionT1546.016 Installer Packages; T1059.007 JavaScriptpostinstall (wave one) and preinstall (wave two) lifecycle hooksDisable install scripts in CI; allowlist the few that need them
StealthT1036.005 Match Legitimate Resource Name or Location; T1678 Delay ExecutionPayload masquerades as a Bun installer and forks into a detached background processAlert on package installs downloading runtimes
Credential accessT1552.001 Credentials In Files; T1552.005 Cloud Instance Metadata API; T1555.006 Cloud Secrets Management Stores; T1528 Steal Application Access Token.npmrc, environment variables, AWS and GCP metadata endpoints, cloud secret stores; TruffleHog run against the file systemNo long-lived secrets on runners; IMDSv2 and metadata restrictions; short-lived credentials
Credential accessT1003.007 Proc Filesystem (S9043)Runner process memory scraped for short-lived identity tokens, then exchanged for npm trusted-publisher tokensSeparate release jobs from jobs that install third-party code
Lateral movementT1550.001 Application Access Token; T1021.007 Cloud Services (S9043)Stolen npm tokens used to enumerate and republish packages; AWS SSM Send-Command to reach EC2Granular, single-package tokens; restrict SSM permissions
Execution in pipelinesT1677 Poisoned Pipeline ExecutionMalicious .github/workflows/discussion.yaml; infected host registered as a self-hosted runner named SHA1HULUDBranch protection; review workflow changes; alert on new runners
Persistence (S9043)T1543.001 Launch Agent; T1053.006 Systemd Timers; T1546 Event Triggered Executiongh-token-monitor daemon polling GitHub every 60 seconds; hooks in AI agent configurationEndpoint monitoring of user launch agents and systemd user units
ExfiltrationT1567.001 Exfiltration to Code Repository; T1567.004 Exfiltration Over WebhookPublic repository named Shai-Hulud (or a generated name) under the victim's account; double Base64 encoded JSON; webhook.siteBlock webhook.site; alert on new public repositories
Persistence and impactT1098 Account Manipulation; T1485 Data DestructionPrivate repositories switched to public; home directory wipe fallbackOrg policy blocking visibility changes; backups of developer workstations

How they abuse identities and credentials

Shai-Hulud is the clearest example so far of a worm that propagates through non-human identities. Each credential type plays a different role.

CredentialHow the worm uses itControl that breaks it
npm publishing token (classic or granular)Republish the owner's packages with the payloadTrusted publishing; "Require two-factor authentication and disallow tokens" in package settings
GitHub personal access tokenCreate exfiltration repositories, push workflows, flip repository visibility, register runnersFine-grained PATs scoped to named repositories; short expiry; org approval. See the GitHub Personal Access Tokens Security Guide
CI OIDC identityMint short-lived publish tokens from inside a compromised job (Mini Shai-Hulud)Bind trust to a specific workflow, branch and protected environment with required reviewers
Cloud access keys and instance rolesRead secret stores; move to EC2 through SSMWorkload identity federation; least privilege; no secret store read on build roles
Bot and automation tokensEntry point: NHIMG's breach analysis of the second wave describes a bot PAT stolen through a pull_request_target workflowNever run untrusted pull request code with secrets; minimise bot scopes

The common thread is long-lived or broadly scoped credentials sitting where third-party code runs. See the npm Tokens Security Guide and the CI/CD Pipeline Identity Security Guide.

Notable incidents

  • First wave, September 2025: GitHub was notified on 14 September; trojanised versions starting with @ctrl/tinycolor followed, CISA issued an alert on 23 September and GitHub removed more than 500 packages and blocked uploads matching the malware's indicators. Unit 42 notes initial access may have come from phishing that impersonated npm. See the Shai-Hulud first wave analysis.
  • Second wave, November 2025: Unit 42 counted more than 25,000 malicious repositories across about 350 users and assessed with moderate confidence that a large language model generated part of the bash tooling. The Shai-Hulud campaign that reached 25,000+ GitHub repositories breach page covers the CI-heavy infection pattern and npm's revocation of classic tokens in December 2025.
  • Mini Shai-Hulud, 2026: SAP Cloud Application Programming Model packages were compromised on 29 April 2026, with stolen data encrypted and exfiltrated through public GitHub repositories, followed by further waves. The Mini Shai-Hulud SAP packages breach page shows how attacker code inside a pipeline could publish through trusted publishing.
  • Platform response: GitHub announced that npm publishing would narrow to local publishing with mandatory 2FA, granular tokens limited to seven days and trusted publishing, with classic tokens and TOTP 2FA deprecated in favour of FIDO-based 2FA.

Detection and defence

What to look for

  • GitHub audit log: repositories created with the name Shai-Hulud or the description "Sha1-Hulud: The Second Coming", repository visibility changes from private to public, new workflow files such as discussion.yaml, and self-hosted runners registered with unexpected names such as SHA1HULUD. See the GitHub Audit Log Detection Guide.
  • npm registry: new versions of your packages published outside the release workflow, or by a token rather than trusted publishing.
  • Build and endpoint telemetry: npm install spawning curl or PowerShell to fetch Bun, node processes running TruffleHog, outbound requests to webhook.site, and on CI runners, processes reading other processes' memory.
  • Cloud logs: secret store reads (GetSecretValue and equivalents) and SSM Send-Command calls from build identities that do not normally make them.
  • Developer hosts: new user launch agents or systemd user services such as gh-token-monitor, and unexpected edits to AI agent and editor configuration.

Containment steps after exposure

  1. Identify affected versions in lockfiles, including nested dependencies, and in artifact caches and proxies, as CISA advised.
  2. Pin to known good versions and rebuild from clean runners.
  3. Rotate every credential reachable from affected hosts and runners: npm, GitHub, cloud, Kubernetes, CI, SSH keys and third-party API keys. Revoke before re-issuing.
  4. Remove worm artefacts: exfiltration repositories, injected workflows, rogue self-hosted runners, unexpected GitHub Apps and OAuth apps, and restore repository visibility.
  5. Check publish history for every package the exposed identities could publish and deprecate malicious versions.
  6. Monitor exposed credentials for reuse for at least 30 days. The Malicious Package Worm Response Playbook sets out roles and evidence.

Prevention, in rollout order

  1. Move publishing to trusted publishing on GitHub Actions, GitLab CI/CD or CircleCI cloud (npm CLI 11.5.1 or later; self-hosted runners are not supported), then set packages to require 2FA and disallow tokens. Consider allowing only npm stage publish so a maintainer approves each release. See the npm Trusted Publishing and Provenance Guide.
  2. Disable lifecycle scripts in CI with ignore-scripts and use npm ci against a committed lockfile; test on one pipeline first and allowlist packages that genuinely need build scripts. Roll back per project if a native module fails to build. See the npm Install-Time Security Guide.
  3. Add a release cooldown in your registry proxy so brand-new versions are not installed for a set period; most waves were removed within hours to days.
  4. Split jobs: dependency install and test jobs get no publishing or cloud write credentials; release jobs run in protected environments with reviewers.
  5. Harden GitHub: phishing-resistant MFA for maintainers, branch protection, secret scanning, block repository visibility changes by members, and restrict self-hosted runner registration.

Decision guidance

  • Package publishers gain most from trusted publishing plus disallowing tokens; it removes the stored credential the first wave relied on.
  • Package consumers gain most from cooldowns, lockfiles and disabled install scripts; they cannot control maintainers' tokens.
  • Small teams on hosted CI can adopt all of this in days; large estates should start with the repositories that publish public packages and the runners with cloud write access.

Metrics

  • Token-free publishing: percentage of published packages using trusted publishing with tokens disallowed.
  • Script exposure: percentage of CI pipelines running installs with lifecycle scripts disabled.
  • Secret reach: number of install or test jobs with access to publishing or cloud write credentials (target: zero).
  • Rotation time: hours from worm advisory to full rotation of exposed credentials.
  • Cooldown coverage: percentage of dependency resolutions passing through a proxy with a minimum release age.

Framework mapping

Control areaNIST CSF 2.0NIST SP 800-53 Rev. 5
Supplier and component riskGV.SC-07SR-3, SR-11
Build configuration and least functionalityPR.PS-01SA-10, CM-7
Credential management for publishing and cloudPR.AA-01IA-5
Monitoring of build and developer environmentsDE.CM-09SI-4

Practitioner checklist

  • Search GitHub audit logs for Shai-Hulud repositories, visibility flips, discussion.yaml workflows and unexpected self-hosted runners.
  • Move every published package to trusted publishing and disallow tokens.
  • Scope OIDC trust to one workflow, branch and protected environment with reviewers.
  • Disable install scripts in CI and pin dependencies with committed lockfiles.
  • Apply a minimum release age to new package versions in the registry proxy.
  • Remove publishing and cloud write credentials from install and test jobs.
  • Block webhook.site egress from build networks.
  • Pre-agree a rotation runbook covering npm, GitHub, cloud, Kubernetes, CI and SSH credentials.
  • Monitor developer hosts for new launch agents, systemd user units and AI tool config changes.

Standards and references

Related NHI Mgmt Group resources: Malicious Package and Dependency Confusion Guide · npm Tokens Security Guide · Malicious Package Worm Response Playbook · GlassWorm VS Code Extension Worm Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.