Hackers Compromise Over 170 npm Packages In Shai-Hulud Supply Chain Attack
Hackers have compromised more than 170 npm packages and two PyPI packages in a new Shai-Hulud supply chain attack aimed at stealing developer credentials, cloud keys, and CI/CD secrets.
JFrog Security Research says the affected packages receive more than 200 million downloads per week, which makes the incident a major risk for development teams, build systems, and cloud environments.
Access content across the globe at the highest speed rate.
70% of our readers choose Private Internet Access
70% of our readers choose ExpressVPN
Browse the web from multiple devices with industry-standard security protocols.
Faster dedicated servers for specific actions (currently at summer discounts)
The campaign, tracked as “Shai-Hulud: Here We Go Again,” uses malicious npm loaders and PyPI import-time payloads to run inside developer machines and automated pipelines. Once active, the malware searches for secrets and tries to use stolen access to spread into more packages.
What happened in the Shai-Hulud attack
The attack targeted trusted software packages used by developers and enterprise build systems. Instead of going after end users directly, the malware focused on the tools and workflows that developers rely on to build and publish software.
In the npm ecosystem, compromised packages carried a malicious preinstall loader and an obfuscated JavaScript payload. That payload could run during package installation, harvest credentials, and look for npm publishing access.
In the Python ecosystem, the compromised PyPI packages used an import-time downloader. This means the malicious code could run when a Python script imported the affected package, then download a remote payload from attacker-controlled infrastructure.
| Area | Reported details |
|---|---|
| Campaign name | Shai-Hulud: Here We Go Again |
| Threat group | TeamPCP |
| Affected ecosystems | npm and PyPI |
| Reported scale | More than 170 npm packages and 2 PyPI packages |
| Weekly download exposure | More than 200 million downloads across affected packages |
| Main risk | Credential theft and self-propagation through trusted publishing paths |
Why this attack is dangerous
The most concerning part of the campaign is its worm-like behavior. The malware does not simply steal secrets from one infected system and stop.
Once it finds npm tokens or trusted publishing credentials, it can scan for packages the victim account can publish. It can then modify those packages, increase their version numbers, inject malicious code, and republish infected versions.
That approach turns trusted development accounts and release pipelines into distribution channels. A package can look legitimate because it comes from a real project, while still carrying malicious code inside the release.
How the attackers abused build systems
Several researchers say the campaign abused modern CI/CD workflows rather than relying only on stolen passwords. In the TanStack compromise, attacker-controlled code reportedly reached a trusted release path through GitHub Actions workflow behavior and cache poisoning.
When a later release workflow restored the poisoned cache, the attacker-controlled payload could extract identity tokens from the runner environment. Those tokens helped publish malicious package versions through trusted automation.
This matters because provenance and trusted publishing systems can confirm where a package came from, but they cannot always prove the code itself was safe. If attackers compromise the build process, a malicious package can still appear to come from a trusted source.
Which packages and projects were affected
The campaign affected packages across several high-profile namespaces and projects. Public alerts and research posts named TanStack, Mistral AI, UiPath, OpenSearch, Squawk, and Guardrails AI among the affected areas.
NHS England’s cyber alert listed examples including @tanstack/react-router, @mistralai/mistralai, @opensearch-project/opensearch, @uipath/robot, @tanstack/vue-router, mistralai 2.4.6 on PyPI, and guardrails-ai 0.10.1 on PyPI.
Wiz also noted that later analysis found a payload bug that made some @uipath and @mistralai npm cases non-functional. That does not remove the wider risk, because teams may still need to investigate exposure, clean environments, and rotate secrets after contact with malicious packages.
| Ecosystem | Examples named in public alerts |
|---|---|
| npm | @tanstack/react-router, @mistralai/mistralai, @opensearch-project/opensearch, @uipath/robot |
| PyPI | mistralai 2.4.6, guardrails-ai 0.10.1 |
| Developer targets | Local workstations, CI/CD runners, release pipelines, internal build systems |
What the malware tries to steal
JFrog says the payload looks for a wide range of secrets across developer machines and cloud environments. That includes local credentials, service tokens, cloud metadata, Kubernetes secrets, and configuration files used by developer tools.
The malware targets GitHub tokens, npm credentials, AWS keys, GCP secrets, Azure secrets, Kubernetes service account tokens, HashiCorp Vault tokens, SSH keys, Docker credentials, Terraform state files, shell histories, and .env files.
The updated PyPI payload also targets password managers and developer tooling. JFrog says it attempts to collect data from tools such as 1Password, Bitwarden, pass, gopass, Claude Desktop configuration, VS Code MCP configuration, Cursor MCP configuration, Codeium, Continue, OpenCode, Kilo, and Zed settings.
- GitHub and npm tokens
- AWS, GCP, and Azure credentials
- Kubernetes service account tokens
- HashiCorp Vault tokens
- SSH keys and Docker credentials
- Terraform state files and .env files
- Password manager entries when accessible
- Developer tool configuration files
The dead-man switch changes the cleanup order
JFrog warned that teams must remove the malware’s persistence mechanisms before revoking GitHub tokens. The reason is a dead-man switch that can react when stolen access gets revoked.
On affected systems, the malware can install a background monitor that checks GitHub access. If the token no longer works, it can trigger destructive behavior on the machine.
That makes the response order important. Teams should isolate affected machines and CI/CD runners first, remove persistence, confirm cleanup, and only then rotate GitHub, npm, cloud, Kubernetes, Vault, SSH, and Docker credentials.
What developers and security teams should do
Any team that installed or imported affected packages should treat the related environment as compromised. This applies to local machines, build workers, CI/CD runners, and automation accounts that may have held secrets.
Developers should remove affected package versions, inspect lockfiles, rebuild CI/CD runners from clean images, and invalidate build caches that may have restored malicious content.
Security teams should also search GitHub accounts and organizations for suspicious repositories, campaign markers, and commits created with unusual automation-like identities. JFrog specifically recommends looking for suspicious commits authored as [email protected] and repositories using campaign-related descriptions.
- Isolate affected developer machines and CI/CD runners.
- Remove persistence files and background services linked to the malware.
- Uninstall affected npm and PyPI package versions.
- Inspect lockfiles and dependency trees for malicious versions.
- Rebuild runners from clean images.
- Invalidate poisoned build caches.
- Rotate GitHub, npm, cloud, Kubernetes, Vault, SSH, and Docker credentials after cleanup.
- Search GitHub for suspicious repositories, commits, and branch names.
- Block known campaign infrastructure at the network level.
- Pause unnecessary dependency upgrades while the campaign remains active.
Why software supply chain attacks keep spreading
This campaign shows how attackers now target the trust behind software delivery. Package managers, release workflows, and automated build systems help teams move quickly, but they also create paths that attackers can abuse.
When a malicious package runs inside a developer environment, it may gain access to secrets that protect source code, cloud accounts, and production systems. If those secrets allow publishing access, the same attack can move from one project to the next.
The Shai-Hulud campaign also shows why teams cannot rely on package reputation alone. A familiar project name, a valid release pipeline, or a trusted namespace does not guarantee that a specific version is safe.
FAQ
Shai-Hulud: Here We Go Again is a software supply chain attack that compromised npm and PyPI packages to steal developer secrets and spread through trusted publishing workflows.
JFrog reports that the campaign affects more than 170 npm packages and 2 PyPI packages. Other researchers use different totals because they count package names, versions, and total affected artifacts differently.
The malware targets GitHub tokens, npm credentials, cloud keys, Kubernetes service account tokens, Vault tokens, SSH keys, Docker credentials, .env files, Terraform state files, and developer tool configuration files.
Developers should isolate affected systems, remove malware persistence, uninstall malicious package versions, inspect lockfiles, rebuild CI/CD runners from clean images, invalidate caches, and rotate secrets only after cleanup.
Read our disclosure page to find out how can you help VPNCentral sustain the editorial team Read more
User forum
0 messages