Managed SOC Services
Aug 8, 2026
Karan Patel

Shai-Hulud: Self-Replicating Malware Targeting the npm Ecosystem

Shai-Hulud: Self-Replicating Malware Targeting the npm Ecosystem

details hero

Software supply chain attacks have followed a familiar shape for years. An attacker compromises a package, waits for downstream installs, and harvests whatever the payload was designed to take. The compromise is finite. It affects the package that was poisoned and the projects that consumed it, and it stops there.

Shai-Hulud broke that shape. Researchers tracking the campaign from 16 September 2025 described it as the first self-replicating supply chain attack, using GitHub Actions to infect repositories consuming any previously infected package. Rather than waiting to be installed, it used what it stole to publish itself into new packages, which were then installed by new victims, which produced more stolen credentials.

CISA subsequently reported that the worm compromised over 500 packages, with the malware scanning environments for credentials and specifically targeting GitHub personal access tokens and API keys for AWS, Google Cloud, and Azure.

The mechanics are worth understanding in detail, because the properties that made this campaign effective are structural features of how modern development works rather than anything specific to npm.

How the Attack Worked

Each stage exploited a legitimate capability rather than a vulnerability.

It Started With Phishing

The chain began with a phishing email disguised as an npm security alert, which tricked a developer into surrendering credentials, after which the attacker took over the account and uploaded a malicious package. The campaign appears to have originated from credential harvesting that spoofed npm and asked developers to update their multi-factor authentication settings.

There is no exploit here. A maintainer was phished, and maintainer accounts hold publishing rights to packages that millions of projects consume.

Installation Executed Code

When the package was installed, it executed JavaScript and embedded shell scripts to establish persistence and begin stealing information. The worm used post-install script functionality to establish secondary and tertiary infections.

Package manager lifecycle scripts run arbitrary code at install time by design. That design decision is convenient and long-standing, and it means installing a dependency is functionally equivalent to executing untrusted code on the machine and in the pipeline that installs it.

It Harvested Everything Reachable

The malware harvested AWS, GCP, and Azure credentials using TruffleHog, a legitimate secret-scanning tool repurposed to find secrets rather than remove them.

Developer workstations and CI runners are unusually rich targets. They hold cloud credentials, registry tokens, repository access tokens, and environment variables containing secrets for every system the developer or pipeline touches. A single compromised runner frequently yields access considerably broader than a compromised production host.

It Published Itself Onward

An automated process authenticated to the npm registry as the compromised developer, injected code into that developer's other packages, and published the compromised versions back to the registry.

This is the replication mechanism, and it is entirely legitimate activity from the registry's perspective. A maintainer published an update to a package they maintain. Nothing about the transaction is anomalous.

It Established Persistence in Repositories

A shell script took discovered GitHub tokens, identified other repositories those tokens could reach, and added a new GitHub Actions workflow file to them, then triggered it, with the resulting action exfiltrating available secrets.

This is the part organizations underestimate. Removing a malicious package version does nothing about a workflow file committed to a repository, which continues running on every subsequent trigger.

Exfiltration Used Public Repositories

Harvested credentials were uploaded to a public repository through the GitHub API. Hundreds of such public repositories containing exfiltrated credentials were observed, and their public nature meant any attacker could access and misuse those secrets, creating a secondary risk beyond the initial theft.

Using GitHub as an exfiltration endpoint appears to be a preferred method for supply chain attackers because it blends with normal developer activity and bypasses many traditional controls. A CI runner making API calls to GitHub is exactly what a CI runner does.

The Second Variant Escalated

A second, more aggressive variant was detected in late November 2025. It introduced execution during the preinstall phase before installation completes, persistence on runners, and destructive behavior when credential theft failed.

The move to preinstall is significant. It means the code runs before the installation the developer initiated has even finished, narrowing any window for intervention.

Why This Class of Attack Is Structurally Hard

The properties that made Shai-Hulud effective are not bugs anyone can patch.

Install-Time Execution Is a Feature

Lifecycle scripts exist because packages legitimately need to compile native modules, generate configuration, and perform setup. Removing the capability would break a large portion of the ecosystem. It also means every dependency install is a code execution event on a machine holding secrets.

Transitive Dependencies Multiply Trust

A project may declare thirty direct dependencies and resolve a thousand transitively. Every one of those runs with the same privileges during installation. Nobody reviews a thousand packages, and nobody could.

Maintainer Accounts Are High-Value and Lightly Defended

A maintainer of a package with millions of weekly downloads holds effective write access to an enormous number of environments. Many are individuals maintaining projects in their spare time, without organizational security support or enforced multi-factor authentication.

Pipelines Hold Broader Access Than Production

CI systems typically hold production deployment credentials, cloud access, and registry publishing rights. They are also monitored less rigorously than the environments they deploy to, which makes them the most valuable and least defended tier in many organizations.

Teams uncertain whether their build environments generate any security telemetry at all can assess that gap with FoxRadar360, since pipeline visibility is one of the most common blind spots in otherwise mature programs.

The Blast Radius Is Not Yours to Control

Your exposure depended on packages you did not choose, maintained by people you have never met, compromised through an account takeover you could not have influenced.

What Detection Looks Like for This

Behavioral signals matter more than indicators here, because the payload changed while the operational pattern persisted.

Behavioral detection is essential precisely because the payload can change form while preserving the same operational steps.

Signals Worth Instrumenting on Build Systems

Outbound connections from CI runners to destinations outside the expected set. A runner that normally talks to your registry, your cloud provider, and your repository host should not be reaching arbitrary webhook endpoints.

Credential scanning tool execution. Legitimate secret scanning happens in defined pipeline stages. Execution of scanning utilities during a dependency install is not normal.

Repository creation via API from a build context. Creating a new repository is rarely something a build job should do.

Workflow file modifications outside normal change process. New workflow definitions appearing without a corresponding reviewed pull request are high-signal events.

Repository visibility changes. Private repositories becoming public is one of the clearest indicators available and warrants immediate escalation.

Package publishing outside release process. Versions published to a registry without a corresponding release pipeline run.

Filesystem enumeration during install. Broad scanning of home directories, credential files, and environment configuration during a package installation.

Signals in the Cloud and Identity Layers

Because the objective was credentials, the follow-on activity appears elsewhere: new access keys created, role trust policies modified, unusual API activity from credentials associated with build systems, and authentication from infrastructure inconsistent with your pipeline's normal source addresses.

Correlating pipeline activity with cloud control plane and identity telemetry is what turns a plausible-looking build event into a detected intrusion, which is why treating CI as a monitored environment rather than an internal utility matters so much.

Why Indicators Alone Failed Here

The infrastructure changed between variants and the package list grew continuously. Organizations relying on a published list of compromised package versions were always working from a snapshot that was out of date, while behavioral detection on install-time activity would have caught variants that no list included yet.

Responding to a Supply Chain Worm

The critical point is that removal is not remediation.

Removing the compromised package does not end the compromise, and full credential rotation plus runner persistence auditing are required.

Assume Every Reachable Secret Is Compromised

Anything present in the environment during execution should be treated as exposed: cloud access keys, registry tokens, repository personal access tokens, database credentials, API keys in environment variables, and SSH keys on the affected machine.

Rotating all potentially affected keys across the repository host, the registry, and cloud providers without delay is the correct default. The public exfiltration repositories make this urgent, since the stolen material was available to anyone, not only the original actor.

Hunt for Persistence

Check every repository the compromised tokens could reach for unauthorized workflow files, modified existing workflows, new deploy keys, added collaborators, and new webhooks. Persistence established through the repository survives package removal entirely.

Audit self-hosted runners for persistence mechanisms and rebuild rather than clean where there is any doubt.

Determine Exposure Window and Scope

Identify when the compromised versions entered your dependency tree, which builds ran during that window, and which environments those builds touched. This requires retained pipeline and cloud logs, which is one more reason retention deserves more investment than it usually receives.

Check for Onward Publishing

If your own packages are published from an affected environment, verify that no versions were published outside your release process, and review recently published versions for injected code.

Review What the Stolen Credentials Reached

Rotation stops future use. It does nothing about what happened before you rotated. Review cloud audit logs for activity attributable to the exposed credentials during the exposure window.

Reducing Exposure Before the Next One

There will be a next one. These measures reduce what it reaches.

Disable Install Scripts Where Practical

Package managers support installing without running lifecycle scripts. This breaks some packages, so it requires an allowlist for the ones that genuinely need it, but it removes the primary execution vector for this entire attack class.

Pin Dependencies and Use Lockfiles

Pinned versions with integrity hashes mean a compromised new release does not enter your build automatically. Update deliberately with review rather than resolving to latest at build time.

Isolate and Ephemeralize Build Environments

Runners should be ephemeral, network-restricted to the destinations they actually need, and holding only the credentials required for the specific job. A runner with broad outbound access and long-lived cloud keys turns a dependency compromise into a cloud compromise.

Replace Static Credentials With Short-Lived Tokens

Workload identity federation lets a pipeline prove what it is and receive a time-limited token, which removes the stored secret that this worm was designed to steal. Where static credentials remain, scope them narrowly and rotate them on a schedule.

Enforce Publishing Controls

Require multi-factor authentication for publishing, use trusted publishing mechanisms tied to verified workflows rather than long-lived tokens, and require review before release for packages your organization maintains.

Monitor the Pipeline as Production

Collect build system logs, runner process and network telemetry, and repository audit events into the same monitoring that covers production. Correlate them with cloud and identity activity so a compromised build surfaces as an incident rather than as a strange line in a build log nobody reads. Bringing pipeline telemetry into a correlated detection layer is part of how FoxRadar360 approaches software supply chain coverage.

Maintain a Dependency Inventory

A current software bill of materials turns the question of whether you are affected from a multi-day investigation into a query. During a fast-moving campaign where the compromised package list grows hourly, that difference determines whether you respond in hours or days.

Key Takeaways

Shai-Hulud matters less as a specific incident than as a demonstration. It proved that a supply chain compromise can propagate autonomously, using stolen publishing rights to reach new victims without any further operator involvement, and that the credentials it collects are sufficient to keep the cycle running.

Nothing in the chain required a vulnerability. A maintainer was phished, install-time script execution ran the payload, legitimate secret-scanning tooling found the credentials, the registry accepted a publish from an authenticated maintainer, and exfiltration flowed through the same platform developers use all day.

Three lessons carry forward regardless of which registry the next campaign targets. Build systems and developer workstations hold broader access than most production hosts and receive a fraction of the monitoring, which makes them the highest-leverage place to add visibility. Indicator lists cannot keep pace with a self-replicating campaign, so detection has to work from behavior: unexpected outbound connections from runners, credential scanning during installs, workflow files appearing outside review, and repositories changing visibility. And removal is not remediation, because persistence lives in repositories and runners while the stolen credentials live wherever the attacker put them.

The practical work is unglamorous: disable install scripts where you can, pin dependencies, make runners ephemeral and network-restricted, replace static keys with short-lived federated credentials, and treat your pipeline as a monitored production environment rather than an internal convenience.

To review whether activity in your build environments would be detected today, and what a compromised dependency could reach from there, start a conversation with the team at FoxRadar360.

Your Threat-Free Future Is One Click Away

Let FoxRadar360 transform your business into a secure, monitored, and threat-resilient operation. Schedule your SOC demo in seconds, simple and stress-free.  

title-icon
Cloud Monitoring
title-icon
Incident Response
title-icon
Compliance Support
title-icon
Threat Intelligence
title-icon
Intelligent TDIR + CTEM
title-icon
SIEM Integration
title-icon
Endpoint Detection and Response
title-icon
Proactive Cyber Risk Management