← All insights
Security & Trust

The Worm That Learned to Jump: npm → PyPI → Your IDE in 9 Days

June 1: npm packages. June 3: new evasion technique. June 5: IDE config poisoning. June 7: PyPI. The Shai-Hulud supply chain worm crossed three attack surfaces in nine days. 448 artifacts. The security industry couldn't keep up.

· 9 min read
Share on X LinkedIn

Day 1: The Registry Attack

On June 1, 2026, Wiz Research disclosed that 32 packages under @redhat-cloud-services — Red Hat's official npm scope — had been compromised. The vector: a Red Hat employee's GitHub session cookie, sitting in infostealer logs since April 13. Seven weeks of exposure. The attacker used the credential to push orphan commits to RedHatInsights repositories, bypassing code review entirely. GitHub Actions workflows minted OIDC tokens. The attacker published 96 malicious versions with valid, forged SLSA provenance attestations.

The payload: a 4.29 MB obfuscated dropper executed via preinstall hooks. It harvested credentials from GitHub, npm, AWS, Azure, GCP, SSH keys, and CI/CD secrets. Then it did something no previous supply chain attack had done at this scale: it self-propagated. Every npm package the infected developer could publish was automatically republished with the worm inside. The Shai-Hulud family had learned to spread.

7 weeks
Time from credential leak to exploitation
Employee credential in infostealer logs since April 13. Attack executed June 1. Source: Wiz Research.
32 packages, 96 versions
Red Hat packages compromised
Under @redhat-cloud-services scope. ~117,000 weekly downloads. Source: Wiz, Microsoft.

Day 3: The Scanner Bypass

Security tools adapted. Scanners started monitoring preinstall and postinstall hooks — the mechanism Miasma used on Day 1. Two days later, Wave 2 bypassed them.

The technique: Phantom Gyp. A 157-byte binding.gyp file dropped alongside the package. Node's native module build system — node-gyp — uses gyp's command substitution syntax: any string wrapped in <!() is executed as a shell command. During npm install, when node-gyp processes the binding.gyp file, the attacker's code runs. No lifecycle scripts. No hooks. No scanner alerts. 57 packages compromised in under two hours, including @vapi-ai/server-sdk with 408,000+ monthly downloads.

The security community had spent 48 hours deploying lifecycle script scanning. Phantom Gyp rendered it irrelevant in minutes.

157 bytes
Phantom Gyp payload size
A single binding.gyp file bypasses all lifecycle script scanners. Source: StepSecurity.
57 packages, 286+ versions
Wave 2 packages compromised
Including @vapi-ai/server-sdk (408K monthly downloads). Source: StepSecurity, SecurityWeek.

Day 5: The IDE Pivot

Day 5 was the paradigm shift. Miasma abandoned package registries entirely. A compromised contributor account pushed a malicious commit to Azure/durabletask — a Microsoft Azure repository. The commit planted .mcp.json and IDE configuration files. When a developer opened the repository in Claude Code, Cursor, or Gemini CLI, the files triggered automatic execution of the credential-harvesting payload. No npm install. No package download. No supply chain in the traditional sense.

GitHub's automated response disabled 73 repositories across four Microsoft organizations — Azure, Azure-Samples, MicrosoftDocs — in 105 seconds. Every GitHub Actions workflow referencing Azure/functions-action@v1 broke instantly. Microsoft recommended developers switch to Azure CLI or Zip Deploy. The mutable @v1 tag pattern — standard in GitHub Actions — meant when the source disappeared, so did thousands of production deployments.

This was not a supply chain attack. It was a development environment attack. The worm had learned to target the IDE itself — the tool developers use to read code, not the code they install.

73
Microsoft repos disabled
Across 4 Microsoft GitHub organizations. 105-second automated sweep. Source: The Register, StepSecurity.

Day 7: The Ecosystem Jump

On June 7, Socket.dev disclosed the Hades wave: the Shai-Hulud worm family had crossed from npm to PyPI. 37 malicious Python wheels used .pth startup hooks — a Python-specific persistence mechanism — to launch a Bun-powered credential stealer. The targets were established bioinformatics tools: dynamo-release, spateo-release, coolbox, ufish. The same credential classes as the npm variants: GitHub, npm, PyPI, cloud providers, Vault, SSH keys, Claude and MCP configs.

Total campaign scope across both registries: 448 artifacts. 411 npm. 37 PyPI. The distinction between 'npm supply chain problem' and 'PyPI supply chain problem' ceased to exist. It was now a package registry problem.

448
Total Shai-Hulud artifacts (all ecosystems)
411 npm + 37 PyPI. Source: Socket.dev Hades analysis, June 7, 2026.

9 Days, 4 Attack Surfaces, 0 Effective Defenses

Registry preinstall hooks → Phantom Gyp binding files → IDE configuration poisoning → cross-ecosystem PyPI wheels. Each escalation arrived faster than the defense against the previous one could be deployed. SLSA provenance was forged on Day 1. Lifecycle script scanners were bypassed on Day 3. Package registry monitoring was irrelevant on Day 5. npm-specific defenses were useless on Day 7.

The worm source code has been public since May 12, when TeamPCP released the fully weaponized Mini Shai-Hulud toolkit. Anyone can build one. Seven days after the source release, 639 malicious versions were published across 323 packages in a single hour — the largest single-hour attack in npm history. The worm is open source. The evasion techniques are documented. The next operator doesn't need to be as skilled as the first.

What This Means for Every Framework

If your stack touches npm: you were exposed on Day 1. React, Next.js, Angular, Vue, Nuxt, Astro, SvelteKit — all depend on npm install. If your stack touches PyPI: you were exposed on Day 7. Django, Flask, FastAPI — all depend on pip install. If your developers use AI coding agents: you were exposed on Day 5. Claude Code, Cursor, Gemini CLI — all execute project configs on open.

Hugo — compiled Go binary, no npm, no pip, no MCP project configs — was exposed on zero of the nine days. The framework with no supply chain is the framework with no supply chain attack surface. In June 2026, that's not a theoretical advantage. It's the only framework category that didn't have a bad week.

Share this insight
More insights