by datastudy.nl

Field notes for teams tracking critical CVEs and major incidents

Engineering

Shai-Hulud worm now scans 469 credential paths: what to rotate

The Shai-Hulud npm infostealer worm expanded from 189 to 469 credential-scanning paths across dev machines, CI/CD, cloud, and AI tool configs after the [email protected] compromise. Rotate everything.

Comparison of credential-scanning locations in Shai-Hulud variants, showing the jump from 189 hardcoded paths in the open-source version to 469 in the latest keyv@6.0.0 variant across Linux, macOS, and Windows
Shai-Hulud credential-scanning path count by variant. Source: GitGuardian. Data Today benchmark.

What is Shai-Hulud and how is it different now?

The Shai-Hulud npm infostealer worm has expanded its credential-scanning scope from 189 hardcoded paths to 469 locations across developer environments, CI/CD tooling, cloud configurations, and AI tool configs, according to research published by GitGuardian and JFrog in September 2026. The latest variant, first observed in the compromised [email protected] npm package on August 4, 2026, now targets AI coding agents, cryptocurrency wallets, and additional CI/CD and cloud services that previous versions ignored.

Shai-Hulud is a self-replicating credential-stealing worm that targets open-source package ecosystems, primarily npm. It propagates by using stolen package-publishing credentials to modify, version, and republish additional packages, spreading compromise across maintainers and downstream consumers. The malware's evolution reflects a shift in attacker focus: instead of trying to break trust relationships, they are harvesting the credentials that already make those relationships work.

What happened in the [email protected] compromise?

The campaign began at 9:35 a.m. UTC on August 4, 2026, when the [email protected] npm package was infected. The compromise chain quickly spread to the cacheable package and beyond, ultimately affecting more than 800 packages across thousands of versions according to GitGuardian's analysis. JFrog's security research team independently confirmed the scale, identifying over 400 packages across 1700+ versions in their investigation.

The 710 KB JavaScript payload is a newer, differently obfuscated variant of Shai-Hulud. The malware's GitHub repository description reads "Shai-Hulud: Here We Go Again," a clear signal from the threat actors. The payload has four connected objectives:

  • Collect local, CI, cloud, Kubernetes, and Vault secrets.
  • Exfiltrate encrypted results through a dynamic HTTPS endpoint or attacker-created public GitHub repositories.
  • Use stolen npm credentials to publish infected patch releases of every writable package.
  • Use GitHub credentials and GitHub Actions to infect repositories and steal more credentials.
Comparison of Shai-Hulud credential-scanning locations: the open-source version scanned 189 paths while the latest keyv@6.0.0 variant scans 469 paths
Shai-Hulud credential-scanning path count by variant. Source: GitGuardian. Data Today benchmark.

The credential collection is comprehensive. The filesystem collector reads hundreds of configured paths across Linux, macOS, and Windows, including package manager tokens (npm, Yarn, PyPI, Verdaccio), cloud configuration (AWS, Azure, GCP, Alibaba, Tencent, Hetzner), Kubernetes and Helm config, .env files, shell histories, SSH private keys, VPN profiles, browser credential stores, instant messengers, crypto wallet material, AI tool credentials (OpenAI, Anthropic, Claude, Cursor, Codex, Gemini, and others), /etc/shadow, and /proc/self/environ.

How did the 469 credential locations break down by OS?

The expanded scanning scope is not evenly distributed. The breakdown reveals a significant shift in targeting priorities:

Open-source version Latest version
Linux 89 290
Windows 12 50
macOS 88 129

On Windows and macOS, the added paths mostly represent a catch-up with the previous version's Linux collector. On Linux, the changes are much more significant. The malware now attempts to exploit elevated privileges to collect secrets from more locations. Previous versions only targeted files in the current user's home directory. The new one enumerates files across all users on the system, including administrative users. Execution with high privileges would be far more severe.

The malware also expands its secret hunting by targeting configuration files for additional services and software:

  • AI agents: Cursor, OpenClaw, OpenAI Codex, OpenCode, Gemini, Hermes
  • CI/CD: ArgoCD, Jenkins, CircleCI
  • Cloud: Hetzner, Alibaba Cloud, Tencent Cloud
  • Cryptocurrency: Foundry, Brownie, Solana, Electrum

The other collectors (local execution environment, CI/CD runner environments, AWS, Kubernetes, Vault) remain largely unchanged. They already collect most of the data they can access.

How does the malware actually steal credentials?

The collector goes far beyond reading files. JFrog's analysis details several active credential extraction techniques:

  • It runs gh auth token to pull a GitHub token from the CLI.
  • On Linux GitHub Actions runners, it uses sudo python3 to read the Runner.Worker process memory through /proc/<pid>/mem and extracts secret-store objects marked isSecret:true.
  • It resolves AWS credentials from environment, profiles, web-identity tokens, ECS metadata, and IMDSv2, then enumerates Secrets Manager and SSM Parameter Store (with WithDecryption: true) across 17 regions.
  • It reads all accessible Kubernetes Secrets from the in-cluster service account or kubeconfig, and enumerates HashiCorp Vault KV mounts.

The exfiltration path is equally sophisticated. Stolen credentials are encrypted and sent through a dynamic HTTPS endpoint or to attacker-created public GitHub repositories. The malware also uses a previously compromised key to exfiltrate secrets to GitHub. Persistence is achieved through poisoning of Claude and VS Code configuration files.

Why does this matter for builders and operators?

If you installed a compromised package version, you must treat the host as compromised. CI runners and build machines are the highest-value targets and should be rebuilt, not cleaned. This is the core operational consequence.

The Shai-Hulud variant is three threats in one payload: a credential stealer, an npm worm, and a GitHub repository infector. Its propagation does not depend on a fixed package list. One stolen npm token with broad write access can turn every package owned by that publisher into the next wave. GitHub tokens extend the loop by exposing Actions secrets and planting execution hooks where developers are likely to trigger them.

The expanded credential scope means that "secret rotation" is now a much larger task than it was in previous supply-chain incidents. The 469 paths cover not just the usual cloud provider credentials but also AI tool configs, crypto wallets, VPN profiles, browser credential stores, and instant messenger data. If you were caught in this campaign, the blast radius of credential exposure is wider than any prior npm worm.

Shai-Hulud credential paths by OS: Linux jumped from 89 to 290, macOS from 88 to 129, Windows from 12 to 50, between the open-source version and the latest keyv@6.0.0 variant
Shai-Hulud credential-scanning paths by OS and variant. Source: GitGuardian, September 2026. Data Today benchmark.

This campaign also validates the concern we flagged in our coverage of the keyv npm worm's AI agent hooks: AI coding tools are now a primary target for credential theft. The addition of Cursor, OpenAI Codex, Gemini, and Claude config poisoning to the malware's playbook means that any developer using AI-assisted coding is a potential victim.

What should I do if I might be affected?

JFrog's incident response guidance is clear and sequential:

  1. Revoke and rotate credentials. Revoke all npm tokens available to affected users and CI jobs, starting with tokens that have bypass_2fa and write permission. Revoke GitHub PATs, OAuth tokens, and Actions tokens exposed to affected systems. Then rotate everything else present on the host or runner: AWS, Azure, GCP, Kubernetes, Vault, database, SSH, VPN, AI-service, and wallet credentials. Assume any secret the collector could read was read.

  2. Search all branches, not just default branches, for the compromised versions. The malware plants hooks in GitHub Actions workflows, so check every branch for modified workflows.

  3. Rebuild, do not clean. Disable or remove the compromised versions. Clear package-manager caches and existing node_modules trees. Rebuild CI runners and developer environments from clean images.

  4. Publish clean package versions only after publisher credentials and trusted-publishing configuration are replaced. Do not republish with the same credentials.

The malware's source code was open-sourced by the Team PCP threat actor in May 2026, which means future waves are likely. The open-source version collected secrets from 189 locations. The latest version collects from 469. The trajectory is clear.

The long tail of secrets sprawl

The Shai-Hulud evolution is a map of where credentials actually live in modern development environments. The jump from 189 to 469 paths is an attacker's reconnaissance of your secrets sprawl, and they found 280 new places to look. Your rotation playbook needs to cover the same ground.

Sources