Phantom Gyp — Miasma wave 4: self-propagating npm worm via binding.gyp (June 2026)
TL;DR
A fourth wave of the Miasma / Shai-Hulud worm lineage hit npm on June 3–4, 2026, using binding.gyp instead of preinstall/postinstall scripts to run malicious code at install time — a technique StepSecurity named "Phantom Gyp." Snyk tracks it as Node-gyp Supply Chain Compromise June 2026; 57 packages / 286+ malicious versions (including @vapi-ai/server-sdk with 408K+ monthly downloads as the highest-profile victim) were published. Same credential-theft and self-propagation core as prior waves, with a novel install-time primitive plus forged SLSA v1 provenance attestations on repackaged malicious versions — green "verified provenance" badges are not safety.
What happened
On 2026-06-03 (and continuing through June 4), a threat actor published 57 malicious npm packages that use native-addon build plumbing (binding.gyp + node-gyp) to execute a malicious payload at npm install time. Unlike preinstall/postinstall lifecycle hooks — which many npm audit tools flag by default — binding.gyp triggers code execution via the native build step and is not blocked by --ignore-scripts unless native addons are also disabled.
What the payload does:
- Steals credentials (cloud keys, GitHub tokens, .env files, SSH keys)
- Injects malicious GitHub Actions workflows (same .github/workflows/*.yml shape as Megalodon)
- Exfiltrates stolen credentials to attacker C2
- Self-propagates by publishing additional poisoned npm packages using stolen npm tokens (worm behavior)
Largest victim: @vapi-ai/server-sdk — the official Vapi.ai voice AI server SDK with 408,000+ monthly downloads was among the first packages hit, at 23:30 UTC on June 3, 2026. The campaign infected 57 packages across 286+ malicious versions in a rolling wave lasting under two hours. A notable escalation: the worm forges SLSA v1 provenance attestations on repackaged malicious versions — reinfected packages display a green "verified provenance" badge and pass standard provenance verification, yet carry the malicious payload (same forgery primitive as the May 19 Mini Shai-Hulud wave that self-minted Sigstore attestations).
June 5 follow-on (Wave 5): On 2026-06-05, credentials stolen during this binding.gyp wave were used to compromise a Microsoft contributor's GitHub account, planting malicious commits in 73 Microsoft GitHub repositories (Azure, Azure-Samples, Microsoft, MicrosoftDocs) and 5 mantine-datatable repos — without touching the npm registry. See 2026-06-miasma-wave5-microsoft-azure-github.md for full details.
Attribution / lineage: The underlying payload and IOCs are consistent with the Miasma / Mini Shai-Hulud worm family (Greek-mythology theming). This is the fourth documented copycat wave after:
1. deadcode09284814 typosquats (May 2026)
2. TrapDoor cross-ecosystem (May 2026)
3. Miasma — @redhat-cloud-services (June 1, 2026)
New primitive: binding.gyp execution. binding.gyp defines how node-gyp builds a native C/C++ addon. When any binding.gyp exists in a package, npm install runs node-gyp build as part of the standard build step — it is not a lifecycle script and is not suppressed by npm install --ignore-scripts. The malicious packages include fake binding.gyp files that trigger node-gyp build, which executes attacker-controlled JavaScript via the configure/build flow. This is the first documented use of this technique at scale in a supply-chain worm campaign.
Am I affected?
# Check for suspicious packages installed since June 3, 2026
# Look for packages with binding.gyp that are not well-known native addons
find node_modules -name "binding.gyp" | while read f; do
pkg=$(echo "$f" | cut -d/ -f1-3)
echo "$pkg"
done
# Check install timestamps in npm cache
npm cache ls 2>/dev/null | grep -E "2026-06-0[34]"
# Snyk scan (updates signatures frequently)
npx snyk test
If you ran npm install on any project between 2026-06-03 00:00 UTC and 2026-06-05 and any transitive dependency pulled in an unfamiliar native-addon package, treat the machine as potentially compromised.
If you are affected
- Rotate all credentials accessible from the affected machine: cloud API keys, GitHub/npm/PyPI tokens, SSH keys.
- Audit GitHub Actions workflows added after 2026-06-02:
git log --all --oneline -- .github/workflows/ - Check for new npm packages published from your account:
npm search --json maintainer:<your-username> | jq '.[].date' - See playbooks/if-you-installed-a-bad-npm-package.md.
Prevention
- Disable binding.gyp execution for packages that don't need native addons: use
--ignore-scriptsAND audit any package that legitimately requires native build. - npm 11.16.0 already ships
allowScripts: off— upgrade now, don't wait for v12: While npm v12 (expected July 2026) will makeallowScripts: offthe out-of-the-box default, npm 11.16.0 (released alongside the June 9 changelog announcement) already includes this flag. You can opt in today: setallow-scripts=falsein your.npmrcand--allow-git/--allow-remotetonone. This blocks both lifecycle scripts (preinstall/postinstall) andbinding.gyp-triggered native builds for all packages — the first npm version that actually stops the Phantom Gyp primitive. Enable it only for specific known-safe native dependencies as needed. See GitHub Changelog: Upcoming breaking changes for npm v12 and The Register coverage.# .npmrc — opt in now with npm >= 11.16.0 allow-scripts=false - Pin npm packages to exact versions + lockfile integrity (
npm ciovernpm installin CI). - Block unexpected workflow file creation via branch-protection rules requiring code review on
.github/workflows/changes. - Monitor npm publish activity for your account/org with StepSecurity's npm package monitoring.
Sources
- Snyk — "Node-gyp Supply Chain Compromise June 2026" — canonical analysis, 57-package scope, "Phantom Gyp" technique detail, payload behavior.
- StepSecurity — "Phantom Gyp" campaign tracking — technique naming, IOC list, timeline.
- The Hacker News — Miasma Supply Chain — family lineage context.
- Cross-reference: 2026-06-miasma-wave5-microsoft-azure-github.md — Wave 5 that used credentials stolen in this wave to hit 73 Microsoft GitHub repos via direct source-repo poisoning.
- Cross-reference: 2026-06-miasma-redhat-cloud-services-compromise.md, 2026-05-shai-hulud-copycat-wave.md, 2026-05-trapdoor-cross-ecosystem-stealer.md.