critical Threat analysis

Phantom Gyp npm Worm Abuses node-gyp Build Hooks

Snyk disclosed a June 2026 npm supply-chain wave that abuses native-addon build behavior through binding.gyp and node-gyp. The Phantom Gyp/Miasma activity affects packages including @vapi-ai, abandoned-package, and autotel packages and should be handled as install-time credential exposure.

#npm#node-gyp#supply-chain#credential-theft#ci-cd
On this page 0% read

    Executive Summary

    On 2026-06-04, Snyk disclosed a self-propagating npm supply-chain campaign that abuses the normal binding.gyp and node-gyp rebuild path used by native Node.js addons [Source 1]. Snyk tracks the technique as Phantom Gyp and ties it to the Miasma / Mini Shai-Hulud style of install-time credential theft and propagation [Source 1] [Source 2].

    This is supply-chain execution, not a passive vulnerable dependency. Affected package installation can execute during npm install, pnpm install, yarn install, or CI build steps before application code is imported. Treat any affected package execution on a developer workstation, CI runner, release builder, or container-build host as possible exposure of npm, GitHub, cloud, SSH, and deployment credentials.

    Source-Watcher Candidate Queue

    candidate_id: "node-gyp-phantom-gyp-npm-worm"
    first_seen: "2026-06-04"
    decision: "publish_ready"
    relationship: "candidate_child_event_of_mini_shai_hulud_miasma"
    dedupe_keys:
      - "technique:phantom-gyp"
      - "tool:node-gyp"
      - "file:binding.gyp"
      - "npm:@vapi-ai/server-sdk"
      - "npm:autotel-trpc"
    starting_sources:
      - "Snyk primary research"
      - "Snyk vulnerability intelligence page"
      - "npm package registry metadata"
      - "GitHub node-gyp project reference"

    Key Facts

    threat_type: "malicious npm package install-time execution"
    ecosystem: "npm"
    technique: "binding.gyp / node-gyp build hook abuse"
    campaign_name: "Phantom Gyp"
    related_family: "Miasma / Mini Shai-Hulud"
    disclosed: "2026-06-04"
    execution_trigger:
      - "npm lifecycle install"
      - "node-gyp rebuild"
      - "native addon binding.gyp processing"
    known_affected_packages:
      - "@vapi-ai/server-sdk"
      - "@vapi-ai/web"
      - "@jagreehal/builder"
      - "abandoned-package"
      - "abandoned-package-2"
      - "autotel-terminal"
      - "autotel-client"
      - "autotel-trpc"
    credential_risk:
      - "npm tokens"
      - "GitHub tokens"
      - "cloud credentials"
      - "SSH keys"
      - "CI/CD deployment secrets"

    Source Confidence and Claim Ledger

    ClaimStatusEvidence
    Snyk disclosed a node-gyp / binding.gyp supply-chain compromise on 2026-06-04.confirmedSnyk’s research article and companion incident page describe the campaign and the Phantom Gyp technique [Source 1] [Source 2].
    The campaign uses normal native-addon build behavior as an execution path.confirmedSnyk specifically highlights binding.gyp and node-gyp as the abused build mechanism; the node-gyp project documents binding.gyp as the native addon build configuration file [Source 1] [Source 4].
    The package list includes @vapi-ai, abandoned-package, and autotel packages.confirmedSnyk’s incident page lists affected packages and versions, and npm registry metadata can be used to confirm package identity and publication history [Source 2] [Source 3].
    Public sources currently prove downstream victim count or cloud-account abuse.not_observedReviewed public sources do not provide a verified victim list or confirmed cloud-control-plane abuse count.

    Impact Determination

    ClassificationCriteriaRequired evidenceHandling decisionClosure condition
    Confirmed compromiseAffected package/version was installed and lifecycle/build execution or credential-harvesting behavior is observed.Lockfile/cache hit plus npm logs, process telemetry, build logs, proxy logs, or endpoint telemetry.Isolate host or runner, preserve package artifacts, and rotate reachable credentials from a clean environment.Affected artifacts are removed, credentials rotated, and downstream audits show no unauthorized write activity.
    Presumed exposedAffected package/version was installed on a credential-bearing workstation, runner, or builder, but runtime telemetry is incomplete.Lockfile, package cache, build log, container layer, or package-manager record.Keep npm, GitHub, cloud, SSH, and deployment credentials in scope.Owners confirm clean rebuilds and credential rotation or accept documented residual risk.
    Potentially exposedDependency inventory shows affected package names but resolved versions or execution are unknown.Manifest, lockfile, registry proxy logs, and build records.Reconstruct package resolution and lifecycle execution.Each hit is dispositioned as confirmed, presumed, or not exposed.
    Not exposedNo affected package names, versions, caches, build logs, or selectors appear in complete evidence.Negative repository, CI, package cache, endpoint, and proxy searches.Preserve negative evidence and enforce lifecycle-script controls.Evidence coverage includes endpoints, CI, build images, and package mirrors.
    UnknownDependency, cache, endpoint, build, or audit telemetry is missing.Named gap with owner and retention window.Keep reachable credentials in scope until evidence or rotation closes the gap.Missing evidence is recovered or risk owner accepts uncertainty.

    Timeline

    • 2026-06-03 to 2026-06-04: Exposure window used by this post for local searches and audit exports, based on Snyk’s June 2026 disclosure window [Source 1] [Source 2].
    • 2026-06-04: Snyk publishes its analysis of the node-gyp supply-chain compromise and Phantom Gyp behavior [Source 1].
    • 2026-06-05: This Halting Problems refresh found no existing local post for the Phantom Gyp node-gyp campaign and created this report.

    Machine-Readable Event Profile

    {
      "event_id": "node-gyp-phantom-gyp-npm-worm",
      "title": "Phantom Gyp npm Worm Abuses node-gyp Build Hooks",
      "first_seen": "2026-06-04",
      "published": "2026-06-05",
      "severity": "critical",
      "ecosystem": ["npm", "node-gyp", "GitHub Actions"],
      "campaign_context": "Phantom Gyp / Miasma / Mini Shai-Hulud",
      "affected_packages": [
        "@vapi-ai/server-sdk",
        "@vapi-ai/web",
        "@jagreehal/builder",
        "abandoned-package",
        "abandoned-package-2",
        "autotel-terminal",
        "autotel-client",
        "autotel-trpc"
      ],
      "known_malicious_versions": {
        "@vapi-ai/server-sdk": ["0.7.1", "0.7.2", "0.7.3"],
        "@vapi-ai/web": ["2.3.1", "2.3.2"],
        "@jagreehal/builder": ["1.0.0"],
        "abandoned-package": ["1.0.0"],
        "abandoned-package-2": ["1.0.0"],
        "autotel-terminal": ["0.0.1"],
        "autotel-client": ["0.0.1"],
        "autotel-trpc": ["0.0.1"]
      },
      "known_behaviors": [
        "install-time lifecycle execution",
        "binding.gyp native-addon build hook abuse",
        "node-gyp rebuild execution",
        "credential harvesting from developer and CI environments"
      ],
      "primary_sources": [
        "https://snyk.io/blog/node-gyp-supply-chain-compromise-self-propagating-npm-worm-binding-gyp/",
        "https://security.snyk.io/node-gyp-supply-chain-compromise-june-2026",
        "https://www.npmjs.com/",
        "https://github.com/nodejs/node-gyp"
      ]
    }

    Indicators of Compromise

    packages:
      - "@vapi-ai/server-sdk@0.7.1"
      - "@vapi-ai/server-sdk@0.7.2"
      - "@vapi-ai/server-sdk@0.7.3"
      - "@vapi-ai/web@2.3.1"
      - "@vapi-ai/web@2.3.2"
      - "@jagreehal/builder@1.0.0"
      - "abandoned-package@1.0.0"
      - "abandoned-package-2@1.0.0"
      - "autotel-terminal@0.0.1"
      - "autotel-client@0.0.1"
      - "autotel-trpc@0.0.1"
    files:
      - "binding.gyp"
      - "package.json"
      - "package-lock.json"
      - "pnpm-lock.yaml"
      - "yarn.lock"
      - "bun.lock"
    process_patterns:
      - "node-gyp rebuild"
      - "npm install lifecycle script"
      - "native addon build executing during dependency install"
    telemetry_selectors:
      - "Phantom Gyp"
      - "Miasma"
      - "The Spreading Blight"
      - "binding.gyp"
      - "ACTIONS_ID_TOKEN_REQUEST_TOKEN"
      - "NPM_TOKEN"
      - "NODE_AUTH_TOKEN"

    Detection and Hunting

    Use the reusable audit script at scripts/threat-posts/node_gyp_phantom_gyp_audit.py.

    python3 scripts/threat-posts/node_gyp_phantom_gyp_audit.py \
      --repo-root /srv/source-export \
      --node-modules-root /srv/build-cache-export \
      --log-dir /srv/ci-and-endpoint-logs \
      --github-audit-dir /srv/github-audit-export \
      --output hp-node-gyp-phantom-gyp-audit.json \
      --fail-on-hit

    Positive signal: any affected package/version in source, lockfiles, package cache, node_modules, build logs, or GitHub audit exports. Escalation: any positive signal on a workstation or runner with npm, GitHub, cloud, SSH, or deployment credentials moves the environment to presumed exposed.

    KQL: endpoint lifecycle execution

    DeviceProcessEvents
    | where Timestamp between (datetime(2026-06-03T00:00:00Z) .. datetime(2026-06-04T23:59:59Z))
    | where ProcessCommandLine has_any ("node-gyp rebuild", "binding.gyp", "@vapi-ai/server-sdk", "@vapi-ai/web", "autotel-trpc", "abandoned-package")
    | project Timestamp, DeviceName, AccountName, InitiatingProcessFileName, FileName, ProcessCommandLine, FolderPath, ReportId

    Positive signal: npm, pnpm, yarn, node, or node-gyp execution involving affected package selectors. False positives include legitimate native addon builds where no affected package/version is present.

    Splunk: package-manager and CI logs

    index=ci OR index=endpoint OR index=proxy earliest="06/03/2026:00:00:00" latest="06/04/2026:23:59:59"
    ("@vapi-ai/server-sdk" OR "@vapi-ai/web" OR "autotel-trpc" OR "autotel-client" OR "autotel-terminal" OR "abandoned-package" OR "binding.gyp" OR "node-gyp rebuild")
    | table _time host source sourcetype user process command status uri

    Positive signal: affected package resolution, installation, or build execution during the exposure window. Escalate when the host is a CI runner, developer workstation, or release builder.

    Downstream Abuse Audits

    For any confirmed or presumed execution, audit GitHub and registry activity after the first package install. Review workflow edits, new secrets, npm publish events, package dist-tag changes, GitHub token use, cloud access-key creation, and deployments originating from the same host, user, or runner pool. Rotate npm automation tokens, GitHub fine-grained tokens, classic PATs, cloud access keys, SSH deploy keys, and package-registry credentials from clean systems.

    Remediation Gates

    1. Remove affected package versions from lockfiles, caches, internal mirrors, container layers, and build images.
    2. Rebuild release artifacts from clean dependency resolution with lifecycle-script restrictions where feasible.
    3. Rotate credentials reachable from exposed environments.
    4. Preserve the script output, lockfile evidence, package-manager logs, and audit logs as closure evidence.

    Sources

    1. Snyk: Node-gyp supply-chain compromise and Phantom Gyp
    2. Snyk vulnerability intelligence: Node-gyp Supply Chain Compromise, June 2026
    3. npm registry
    4. node-gyp project

    IOC Clipboard

    6 IOCs
    Defang IOCs
    file binding.gyp binding.gyp
    file package.json package.json
    file package-lock.json package-lock.json
    file pnpm-lock.yaml pnpm-lock.yaml
    file yarn.lock yarn.lock
    file bun.lock bun.lock