Miasma npm Phantom Gyp Self-Spreading Worm

Suspected
Discovered Jun 3, 2026

StepSecurity reported the Miasma worm as a 57-package, 286-plus-version npm compromise that abused binding.gyp/Phantom Gyp execution, downloaded Bun, stole CI and developer credentials, and used GitHub repositories as exfiltration and propagation infrastructure.

10
Affected Packages
20
Observables
2
Sources

Analysis

Executive Summary

StepSecurity reported the Miasma worm as a 57-package, 286-plus-version npm compromise that abused binding.gyp/Phantom Gyp execution, downloaded Bun, stole CI and developer credentials, and used GitHub repositories as exfiltration and propagation infrastructure.

This folder ports older Astro-era supply-chain coverage into the canonical hp-posts-info authoring shape so the Next.js/Postgres importer can serve it. The current status is needs_review: the source-backed indicators are captured, but the pass intentionally does not claim fresh artifact diffing beyond the cited primary research.

Key Facts

  • Affected assets: @evolvconsulting/evolv-coder-lite, @jagreehal/workflow, @vapi-ai/server-sdk, ai-sdk-ollama, autotel, autotel-adapters, autotel-audit, autotel-aws, autotel-backends, autotel-cli, autotel-cloudflare, autotel-devtools ....
  • Execution trigger: node-gyp processes binding.gyp shell expansion during npm install.
  • Credential risk: GitHub, OIDC, cloud, package-registry, and developer credentials reachable from impacted CI or developer environments.
  • Relationship: migrated from the older Astro blog supply-chain roundup into a standalone Next.js/Postgres-ready incident folder.

Defender Handling

Run the included scope scanner over repository exports, package caches, CI logs, and endpoint telemetry. Treat matches in live dependency manifests, lockfiles, workflow definitions, or runner process/network logs as exposure signals until the owning team confirms whether the malicious artifact actually executed.

Open Questions

This migration captures coverage and source-backed selectors. Before marking publish-ready, perform fresh artifact diffing, validate current package/action cleanup status, and reconcile exact downstream victim counts from direct maintainer or platform sources.

Sources

  1. StepSecurity primary research. Role: PRIMARY_RESEARCH Impact: Primary source for affected assets, execution trigger, payload behavior, and published IOCs.

Timeline

4 of 4 rows

Timeline
DateEventDescriptionSource
Jun 3, 2026First seenFirst seen recorded for Miasma npm Phantom Gyp Self-Spreading Worm.StepSecurity
Jun 3, 2026DiscoveryDiscovery recorded for Miasma npm Phantom Gyp Self-Spreading Worm.StepSecurity
Jun 3, 2026DisclosureDisclosure recorded for Miasma npm Phantom Gyp Self-Spreading Worm.StepSecurity
Jun 3, 2026Miasma npm Phantom Gyp Self-Spreading WormUnknownStepSecurity

Affected Software

10 of 10 rows

Affected Software
PackageEcosystemVersion RangeStatusConfidenceSource
@vapi-ai/server-sdkunknown0.11.1Malicious65%StepSecurity; haltingproblems.com
@vapi-ai/server-sdkunknown0.11.2Malicious65%StepSecurity; haltingproblems.com
@vapi-ai/server-sdkunknown1.2.1Malicious65%StepSecurity; haltingproblems.com
@vapi-ai/server-sdkunknown1.2.2Malicious65%StepSecurity; haltingproblems.com
ai-sdk-ollamaunknown0.13.1Malicious65%StepSecurity; haltingproblems.com
ai-sdk-ollamaunknown1.1.1Malicious65%StepSecurity; haltingproblems.com
ai-sdk-ollamaunknown2.2.1Malicious65%StepSecurity; haltingproblems.com
ai-sdk-ollamaunknown3.8.5Malicious65%StepSecurity; haltingproblems.com
@evolvconsulting/evolv-coder-liteunknown1.2.0Malicious65%StepSecurity; haltingproblems.com
@jagreehal/workflowunknown1.16.1Malicious65%StepSecurity; haltingproblems.com

IOC Clipboard

20 IOCs
file_pathindex.js
domainapi.github.com
command/proc/{pid}/mem
urlhttps://github.com/oven-sh/bun/releases/download/bun-v1.3.13/
file_pathstub.c
commandnode index.js
domaingithub.com
commandnode-gyp rebuild
file_pathbinding.gyp
commandsudo python3
commandgh auth token
network_patternthebeautifulmarchoftime
hash288f26c2eadcb1a7923fe376d16f5404216cce15d9fc162a4a78574dc7df399a
hashef641e956f91d501b748085996303c96a64d67f63bfeef0dda175e5aa19cca90
hash5926b86b642e00672252953eb30d8f75cfb7797fe3118bd6fa2cfbee92905d61
hashceff7c51d70832c3ec8dd2744b606a23b3c924ef664ae23439b9b742ea154108
hashda39146ef451d1b174a24d00b1e2a45cd38d54e849737f8f35333dcb22175707
network_patternIfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner
network_patternMiasma - The Spreading Blight
commandRunner.Worker

Tested Hunting Scripts

1 of 1 rows

Tested Hunting Scripts
TitleLanguageDescriptionRepositorySource
local repository and exported telemetry scopePythonDoes this scope contain package, workflow, process, filesystem, or network indicators associated with Miasma npm Phantom Gyp Self-Spreading Worm?scripts/local_repository_and_exported_telemetry_scope.pyStepSecurity

Hunt Manifest: local repository and exported telemetry scope

Title
local repository and exported telemetry scope
Question
Does this scope contain package, workflow, process, filesystem, or network indicators associated with Miasma npm Phantom Gyp Self-Spreading Worm?
Telemetry Family
Python
Repository
scripts/local_repository_and_exported_telemetry_scope.py
scripts/local_repository_and_exported_telemetry_scope.pyPython
#!/usr/bin/env python3
import os
import sys
from pathlib import Path

ROOT = Path(sys.argv[1]).resolve() if len(sys.argv) > 1 else Path('.').resolve()
OUT = Path(os.environ.get('OUT', 'hp-miasma-npm-phantom-gyp-worm-scope'))
OUT.mkdir(parents=True, exist_ok=True)

PACKAGES = ["@evolvconsulting/evolv-coder-lite", "@jagreehal/workflow", "@vapi-ai/server-sdk", "ai-sdk-ollama", "autotel", "autotel-adapters", "autotel-audit", "autotel-aws", "autotel-backends", "autotel-cli", "autotel-cloudflare", "autotel-devtools", "autotel-drizzle", "autotel-edge", "autotel-eventcatalog", "autotel-hono", "autotel-mcp", "awaitly", "awaitly-analyze", "awaitly-libsql"]
PACKAGE_VERSIONS = ["@vapi-ai/server-sdk@0.11.1", "@vapi-ai/server-sdk@0.11.2", "@vapi-ai/server-sdk@1.2.1", "@vapi-ai/server-sdk@1.2.2", "ai-sdk-ollama@0.13.1", "ai-sdk-ollama@1.1.1", "ai-sdk-ollama@2.2.1", "ai-sdk-ollama@3.8.5", "@evolvconsulting/evolv-coder-lite@1.2.0", "@jagreehal/workflow@1.16.1"]
FILES = ["binding.gyp", "index.js", "stub.c"]
HASHES = ["288f26c2eadcb1a7923fe376d16f5404216cce15d9fc162a4a78574dc7df399a", "ef641e956f91d501b748085996303c96a64d67f63bfeef0dda175e5aa19cca90", "5926b86b642e00672252953eb30d8f75cfb7797fe3118bd6fa2cfbee92905d61", "ceff7c51d70832c3ec8dd2744b606a23b3c924ef664ae23439b9b742ea154108", "da39146ef451d1b174a24d00b1e2a45cd38d54e849737f8f35333dcb22175707"]
DOMAINS = ["api.github.com", "github.com"]
URLS = ["https://github.com/oven-sh/bun/releases/download/bun-v1.3.13/"]
IPS = []
PROCESS_PATTERNS = ["node-gyp rebuild", "node index.js", "Runner.Worker", "/proc/{pid}/mem", "gh auth token", "sudo python3"]
NETWORK_PATTERNS = ["thebeautifulmarchoftime", "IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner", "Miasma - The Spreading Blight"]

def read_text(path: Path) -> str:
    try:
        return path.read_text(encoding="utf-8", errors="ignore")
    except Exception as exc:
        return f"__READ_ERROR__:{path}:{exc}"

def scan_tree(base: Path, indicators: set[str]) -> list[str]:
    matches = []
    skip = {".git", "node_modules", "vendor", "dist", ".venv", "__pycache__"}
    for current_root, dirs, files in os.walk(base):
        dirs[:] = [d for d in dirs if d not in skip]
        for name in files:
            path = Path(current_root) / name
            text = read_text(path)
            for indicator in indicators:
                if indicator and indicator in text:
                    matches.append(f"{path}: found {indicator!r}")
    return matches

indicators = set()
for group in [PACKAGES, PACKAGE_VERSIONS, FILES, HASHES, DOMAINS, URLS, IPS, PROCESS_PATTERNS, NETWORK_PATTERNS]:
    indicators.update(group)

(OUT / "indicators.txt").write_text("\n".join(sorted(indicators)) + "\n", encoding="utf-8")
matches = scan_tree(ROOT, indicators)
(OUT / "matches.txt").write_text("\n".join(matches) + ("\n" if matches else ""), encoding="utf-8")
print(f"[+] wrote {len(indicators)} selectors and {len(matches)} matches under {OUT}")

Provenance & Sources

2 of 2 rows

Provenance & Sources
SourceTypeReliabilityClaimsEvidence
StepSecuritySecurity Researcher95%1StepSecurity reported the Miasma worm as a 57-package, 286-plus-version npm compromise that abused binding.gyp/Phantom Gyp execution, downloaded Bun, stole CI and developer credentials, and used GitHub repositories as exfiltration and propagation infrastructure.
haltingproblems.comBlog80%1StepSecurity reported the Miasma worm as a 57-package, 286-plus-version npm compromise that abused binding.gyp/Phantom Gyp execution, downloaded Bun, stole CI and developer credentials, and used GitHub repositories as exfiltration and propagation infrastructure.
Miasma npm Phantom Gyp Self-Spreading Worm — Halting Problems