Phantom Gyp Miasma worm hits @vapi-ai/server-sdk and the jagreehal portfolio via binding.gyp
Between 23:30 UTC on 2026-06-03 and ~01:30 UTC on 2026-06-04 the Miasma worm published a malicious 157-byte binding.gyp payload through 57 npm packages and 286+ versions, starting at @vapi-ai/server-sdk (~408k weekly downloads) and cascading across the jagreehal maintainer's autotel-*, awaitly-*, ai-sdk-*, executable-stories-*, node-env-resolver-*, and wrangler-deploy portfolio. GitHub Advisories backfilled the full affected-version set across the autotel-* family and the wider awaitly-* portfolio on 2026-06-29 / 2026-06-30 (16 new autotel-* GHSAs plus expanded awaitly / awaitly-mongo / awaitly-libsql / awaitly-analyze ranges).
- Threat actor
- TeamPCP
- Detected by
- StepSecurity · Socket · Snyk · Sonatype · Semgrep · Chainguard · Corgea · Akamai · Wiz · OX Security
- Also known as
- Miasma v2 · Phantom Gyp · binding.gyp worm · Mini Shai-Hulud
- Ecosystems
- npm
- Packages tracked
- 26
What happened
On 2026-06-03 at 23:30 UTC the Miasma operator (the same TeamPCP / Mini Shai-Hulud lineage behind the 2026-06-01 @redhat-cloud-services wave two days earlier) published four malicious versions of @vapi-ai/server-sdk, the official Vapi.ai voice-AI server SDK with ~408,000 weekly downloads. Within an hour the worm pivoted to the unrelated jagreehal maintainer account and used the stolen publish token to enumerate every package that account owned, republishing a tampered X.Y.(Z+1) patch on every released major branch. The whole campaign was over in under two hours. Final tally: 57 packages, 286+ malicious versions, two distinct maintainer takeovers.
Phantom Gyp: a 157-byte install-time RCE
Instead of the usual preinstall / postinstall lifecycle script hooked off package.json, the worm ships a minimal binding.gyp file. npm treats binding.gyp as a signal that the package contains native C/C++ code and unconditionally invokes node-gyp rebuild during install. The attacker abuses gyp's command-substitution syntax to embed a shell command that runs node index.js (or a Bun bootstrap), then returns a fake source filename so the build succeeds with no visible error. Almost every install-time security scanner (Socket, Snyk, npm audit, JFrog) hooks the lifecycle scripts and never inspects binding.gyp, so the entire exposure window opened and closed before any registry advisory could fire. As of disclosure there is no CVE, GHSA, or OSV record covering the wave.
Payload
The index.js stage downloads a Bun runtime, executes a heavily obfuscated JavaScript credential stealer (the same family used in the 2026-04-30 @cap-js SAP wave and the 2026-05-11 TanStack burst), then harvests AWS IMDSv2, GCP metadata, Azure managed-identity tokens, Kubernetes service-account tokens, HashiCorp Vault reads, GitHub Actions OIDC tokens, npm/PyPI/RubyGems publish tokens, SSH keys, Docker config, and .env files. Exfil is via attacker-controlled GitHub repos created from the stolen gh tokens, and the worm injects a .github/workflows/*.yml step into every repo it can push to so the next CI run re-detonates the chain. The same payload drops backdoor MCP/instruction-override configs into .claude/, .cursor/, and .gemini/ directories so AI-assisted edits inside a poisoned project can be silently steered.
Maintainer impact
The @vapi-ai org takeover yielded a single high-traffic package (@vapi-ai/server-sdk, four malicious versions including 0.11.1). The jagreehal takeover yielded the long tail: the autotel-* OpenTelemetry framework (24 packages including autotel-cli, autotel-cloudflare, autotel-aws, autotel-edge), the awaitly-* async-workflow stack (7 packages, each republished across every released major as X.Y.(Z+1)), the ai-sdk-* Vercel AI SDK helpers (including ai-sdk-ollama at ~120k weekly downloads with malicious 0.13.1/1.1.1/2.2.1/3.8.5), the executable-stories-* BDD test runners, the node-env-resolver family, and the wrangler-deploy Cloudflare Workers tooling. The clean republishes shipped 2026-06-04 to 2026-06-06 carry deprecation notices on the malicious patches reading SECURITY: compromised supply-chain build (2026-06-04 worm) — do not use; upgrade to a known-good release.
- Eighth distinct wave in the Shai-Hulud / Miasma lineage since 2025-09; second wave in three days following the 2026-06-01
@redhat-cloud-servicescompromise. - No GHSA / OSV / npm advisory at disclosure — the worm landed and was unpublished/deprecated faster than the advisory pipelines could ingest, so the npm package-deprecation field is currently the only registry-level signal.
- Downstream coverage: StepSecurity (named the technique "Phantom Gyp"), Snyk (tracker entry node-gyp-supply-chain-compromise-june-2026), Sonatype, Semgrep, Chainguard, Corgea, Akamai, Socket, Wiz, OX Security, and Phoenix Security all republished within ~36 hours.
2026-06-29 / 2026-06-30 advisory backfill
GitHub Advisories caught up on the long tail of the jagreehal portfolio with 21 new GHSA records published 2026-06-29 and 2026-06-30, all CWE-506 / malware-classified. Coverage now includes the full autotel-* framework — autotel-cli (0.8.14), autotel-web (1.12.2), autotel-vitest (0.4.26), autotel-hono (0.4.26), autotel-tanstack (1.13.27), autotel-playwright (0.4.32), autotel-sentry (0.5.13), autotel-plugins (0.19.26), autotel-drizzle (0.0.27), autotel-backends (2.12.26), autotel-pact (0.2.2/1.0.3), autotel-eventcatalog (5 patches), autotel-mongoose (7 patches), autotel-mcp-instrumentation (6 patches), autotel-mcp (28 patches), and autotel-subscribers (28 patches). The awaitly-* portfolio was re-confirmed and extended: awaitly itself (<= 1.33.3), and the per-major patch counts for awaitly-mongo (24), awaitly-libsql (23), and awaitly-analyze (9) now match the registry-side unpublish trail. The pattern across every package is identical to the original wave: a single X.Y.(Z+1) malicious patch on each released major branch, then a clean republish at X.Y.(Z+2) once the maintainer regained control.
Affected packages (26)
- npm
@vapi-ai/server-sdk0.11.1 - npm
ai-sdk-ollama0.13.11.1.12.2.13.8.5 - npm
autotel-backends2.12.26 - npm
autotel-cli0.8.14 - npm
autotel-drizzle0.0.27 - npm
autotel-eventcatalog1.0.12.0.13.0.14.0.25.0.1 - npm
autotel-hono0.4.26 - npm
autotel-mcp0.1.142.0.13.0.14.0.15.0.16.0.17.0.18.0.19.0.110.0.111.0.113.0.114.0.115.0.216.0.117.0.218.0.119.0.120.0.121.1.122.0.123.0.124.0.125.0.126.0.227.0.128.0.329.0.1 - npm
autotel-mcp-instrumentation29.0.230.0.531.0.132.0.133.0.234.0.1 - npm
autotel-mongoose0.0.31.0.22.0.53.0.14.0.15.0.26.0.1 - npm
autotel-pact0.2.21.0.3 - npm
autotel-playwright0.4.32 - npm
autotel-plugins0.19.26 - npm
autotel-sentry0.5.13 - npm
autotel-subscribers4.1.15.0.16.0.17.0.18.0.19.0.110.0.111.0.112.0.113.0.114.1.115.0.116.0.217.0.118.0.319.0.120.0.121.0.122.0.223.0.224.0.125.0.126.0.127.0.228.0.229.0.630.0.431.1.4 - npm
autotel-tanstack1.13.27 - npm
autotel-vitest0.4.26 - npm
autotel-web1.12.2 - npm
awaitly1.33.3 - npm
awaitly-analyze0.24.21.1.12.0.13.0.14.0.15.0.16.0.17.0.18.0.1 - npm
awaitly-libsql0.1.11.0.12.0.13.0.14.0.15.0.16.0.17.0.18.0.19.0.110.0.111.0.112.0.113.0.114.0.115.0.116.0.117.0.118.1.119.0.120.0.121.0.122.0.1 - npm
awaitly-mongo0.1.11.0.12.0.13.0.14.0.15.0.16.0.17.0.18.0.19.1.110.0.111.0.112.0.113.0.114.0.115.0.116.0.117.0.118.0.119.1.120.0.121.0.122.0.123.0.1 - npm
awaitly-postgres0.1.11.0.12.0.13.0.24.0.15.0.16.0.17.0.18.0.19.0.110.0.111.0.112.0.1 - npm
awaitly-visualizer1.0.1 - npm
node-env-resolver6.5.1 - npm
wrangler-deploy1.5.5
Impact
- Install-time RCE: npm auto-invokes
node-gyp rebuildwhen it seesbinding.gyp, sonpm install/npm ciexecutes the worm before any lifecycle script runs - Credential theft from CI/CD runners and developer workstations: GitHub Actions OIDC, AWS, GCP, Azure, HashiCorp Vault, Kubernetes service accounts, SSH keys, npm/PyPI/RubyGems publish tokens, Docker configs
- Self-propagating: stolen npm tokens are used to enumerate every package a victim maintainer owns and republish a poisoned
binding.gyppatch (X.Y.(Z+1)) on every released major - Forged provenance: the worm re-uses the victim's trusted publisher (GitHub OIDC) so the malicious tarballs ship with valid SLSA provenance and Sigstore attestations
- CI/CD persistence: malicious GitHub Actions workflow files are injected into every repo the stolen token can push to, so a single re-run re-detonates the campaign
- AI-assistant tampering: backdoor config files are dropped for Claude Code, Cursor, and Gemini so subsequent AI-assisted edits inside a poisoned project can be steered by the attacker
What to do
- 1Pin and reinstall: remove
node_modules/lockfile entries and pin to the post-incident clean release (e.g.@vapi-ai/server-sdk>= 1.2.0,ai-sdk-ollama>= 3.8.6,autotel-cli>= 0.8.15,node-env-resolver>= 6.5.2,wrangler-deploy>= 1.5.6,awaitly-*>= the post-2026-06-04 clean republish) - 2Treat any developer host or CI runner that ran
npm installagainst an affected version between 2026-06-03 23:30 UTC and 2026-06-04 02:00 UTC as fully compromised; rotate every credential reachable from that host - 3Rotate npm tokens, GitHub Actions OIDC trust, AWS/GCP/Azure keys, Vault tokens, Kubernetes service-account tokens, and SSH keys held by impacted maintainers
- 4Audit recent npm publish history under your maintainers for unexpected
X.Y.(Z+1)patch bumps published between 2026-06-03 and 2026-06-04 - 5Hunt for
binding.gypfiles in repos that have no native code, and for unexpected GitHub Actions workflows pushed within the exposure window - 6Inspect AI-assistant config files (
.claude/,.cursor/,.gemini/) inside cloned victim repos for unexpected MCP / instruction overrides
References
- jagreehal/ai-sdk-ollamaSupply chain compromise: malicious binding.gyp worm harvests CI/CD secrets and injects into GitHub Actions workflows (Issue #975)github.com
- npm@vapi-ai/server-sdk npm registry entry (compromised 0.11.1 deprecated)npmjs.com
- npmai-sdk-ollama npm registry entrynpmjs.com
- npmwrangler-deploy npm registry entry (compromised 1.5.5 deprecated)npmjs.com
- npmawaitly-postgres npm registry entry (compromised 0.1.1–12.0.1 deprecated)npmjs.com
- GitHubGHSA-3729-344x-9v28 — autotel-cli malware advisorygithub.com
- GitHubGHSA-78g2-45pm-5862 — autotel-web malware advisorygithub.com
- GitHubGHSA-m9j7-x8ww-5jwr — ai-sdk-ollama malware advisorygithub.com
- GitHubGHSA-c8c9-7f3h-7c76 — awaitly malware advisorygithub.com