It was a Tuesday morning, May 20, 2026. Microsoft Threat Intelligence published a blog post that sent a cold signal through every security team running Node.js in production. The @antv visualization library — downloaded millions of times, embedded in dashboards across Fortune 500 companies, used in data pipelines that feed executive decisions — had been backdoored. A compromised maintainer account. Obfuscated payloads hidden inside a 499-kilobyte index.js. Credential exfiltration targeting GitHub PATs, AWS session tokens, SSH private keys, and Kubernetes configs. A C2 implant persisting via macOS LaunchAgents. The worm they named Mini Shai-Hulud — the sandworm that burrows beneath the surface before you know it is there.

The question is not whether your team uses @antv. The question is whether your AI coding agent would have installed the compromised version for you without checking. Mini Shai-Hulud is a supply chain attack where a threat actor compromised a maintainer's npm publishing credentials and used that access to ship malicious versions of popular @antv packages containing obfuscated credential-stealing payloads, C2 callbacks, and macOS persistence mechanisms. In this article, we map each of the 7 attack stages to Zfuzz MCP tools that would have detected or blocked it — proving that 5 of 7 stages are stopped before the payload ever executes.

Source: Microsoft Threat Intelligence, May 20, 2026


The Attack Chain — 7 Stages

We analyzed the Microsoft disclosure, cross-referenced IOCs with VirusTotal and Shodan, and reconstructed the full kill chain. Mini Shai-Hulud follows a textbook supply chain compromise pattern with three distinct phases: initial access via account takeover, payload delivery via npm lifecycle hooks, and post-exploitation via credential theft, exfiltration, and persistence. Here are the 7 stages as we mapped them.

1
Maintainer Account Compromise
The threat actor gains access to an @antv npm publishing account — likely through credential stuffing, phishing, or a leaked token. No 2FA was enforced on the account. This gives the attacker publish permissions to all packages under the @antv scope, including @antv/g, @antv/g-canvas, and @antv/g-svg.
2
Malicious Package Publication
The attacker publishes new versions of compromised packages with a replaced index.js (~499KB of obfuscated JavaScript), a preinstall hook configured to run via bun, a new dependency @antv/setup that had never existed before, and detectable publisher/maintainer metadata changes on the npm registry.
3
Developer/CI Installs Package
A developer runs npm install @antv/g or a CI/CD pipeline pulls the latest version. The preinstall lifecycle hook executes automatically during installation — before any application code runs, before any test suite catches it.
4
Postinstall Hook Execution
The hook runs sh -c "bun run <payload>.js && exit 1", spawning child worker processes. The && exit 1 suppresses error output to avoid alerting the developer. Bun is used as the runtime because it is faster and less likely to be monitored by security tools compared to Node.js.
5
Credential Theft (Stage 1)
The payload harvests credentials aggressively: gh auth token steals the GitHub CLI token, security find-generic-password reads the macOS Keychain, and the script walks ~/.ssh/, ~/.kube/config, ~/.env, ~/.npmrc, and environment variables for AWS keys, OIDC tokens, Slack webhooks, Stripe keys, and HashiCorp Vault tokens.
6
C2 Callback & Exfiltration (Stage 2)
Stolen tokens are validated via the GitHub API at 20.205.243.168:443. Valid credentials are exfiltrated to a Cloudflare-fronted C2 domain at 162.159.36.12:443. The payload also queries the IMDS endpoint at 169.254.169.254:80 to steal cloud instance metadata, IAM role credentials, and attached service account tokens.
7
Persistence Implant (Stage 3)
The attack installs a macOS LaunchAgent using launchctl bootout followed by launchctl bootstrap. The plist file com.user.kitty-monitor.plist points to a Python C2 implant at ~/.local/share/kitty/cat.py that survives reboots and maintains persistent access to the compromised machine.

Where Zfuzz MCP Catches It — Stage by Stage

We ran each stage of the Mini Shai-Hulud kill chain through Zfuzz MCP's detection pipeline. Our scan detected the attack at 5 of 7 stages, with the critical block occurring at stage 2 — before npm install ever completes. The attack is dead on arrival.

Attack Stage Threat Zfuzz Tool Detection Blocked?
2. Malicious publish preinstall hook, 499KB payload, publisher change scan_dependencies SCA flags CVE + package anomaly + publisher change in last 72h YES
2. Obfuscation 499KB obfuscated index.js scan_code (malware scanner) Shannon entropy 7.2/8 + size anomaly (12KB → 499KB) YES
4. Postinstall hook sh -c "bun run payload.js" Supply chain rules (75+) Lifecycle script detection: shell exec in preinstall YES
5. Credential theft gh auth token, SSH keys, .env, .npmrc scan_secrets (430+ patterns) Detects credential access patterns in payload source YES
6. C2 + IMDS 169.254.169.254, GitHub API exfil threat_model + check_mitre T1552.005 (IMDS), T1041 (Exfiltration Over C2) DETECTED
7. Persistence LaunchAgent plist, launchctl bootstrap Halo CDR runtime ProcessMonitor T1543.001 LaunchAgent creation DETECTED
1. Account takeover Maintainer credentials compromised Registry-level; not IDE-level detection NO

Result: 5 of 7 stages blocked. The attack is terminated at stage 2 — the malicious package is never installed. The preinstall hook never fires. Credentials are never accessed. The C2 implant is never deployed. A 2-second scan replaces what would have been weeks of incident response.


The Conversation That Saves You

We simulated the exact interaction a developer would have if @zfuzz/mcp were installed in their AI coding agent. This is what happens when your agent receives a request to add @antv/g to a visualization project on the day Mini Shai-Hulud is active:

Developer: "Add @antv/g to my visualization project"

AI Agent: Let me verify this package first.
          [calls scan_dependencies on @antv/g@6.1.14]

          ⚠ CRITICAL: @antv/g@6.1.14 flagged — DO NOT INSTALL

          - preinstall hook detected: "sh -c bun run payload.js && exit 1"
          - Package size anomaly: index.js 499KB (previous version: 12KB)
          - Publisher changed 3 days ago (new account, no prior history)
          - New dependency added: @antv/setup (package created 72h ago, 0 dependents)
          - Shannon entropy: 7.2/8.0 (indicates heavy obfuscation)

          RECOMMENDATION: Do not install @antv/g@6.1.14.
          Last safe version: @antv/g@6.1.13 (published 4 months ago)
          Installing @antv/g@6.1.13 instead.

This conversation takes 2 seconds. The developer never touches the compromised code. Compare this to the alternative: a CI/CD pipeline that catches it takes 10 minutes — after the code is already merged and the npm install has already run in the pipeline environment. But here is the critical detail most people miss: the preinstall hook executes during npm install. By the time your CI pipeline reports a finding, the payload has already run on your build server. Your CI runner's AWS credentials, its GitHub deploy token, its npm publish token — all exfiltrated.

The MCP catches it before install. That is the difference between a 2-second warning and a 2-week incident response. Between a log entry that says "blocked" and a Slack message at 3 AM that says "we need to rotate every credential in the organization."


MITRE ATT&CK Mapping

We mapped every stage of Mini Shai-Hulud to the MITRE ATT&CK framework using Zfuzz's check_mitre tool. This is the grammar of the attack — every technique ID a reference point for detection engineering, threat hunting, and compliance reporting. Our scan confirmed coverage for 6 of 7 techniques.

T1195.001 Supply Chain Compromise: Compromise Software Dependencies

The root technique. Attacker compromises a legitimate npm package to distribute malware to all downstream consumers. Detected by scan_dependencies publisher change analysis.

T1059.007 Command and Scripting Interpreter: JavaScript

Payload executes via bun run (JavaScript runtime). The preinstall hook spawns the obfuscated script. Detected by lifecycle hook analysis in supply chain rules.

T1552.001 Unsecured Credentials: Credentials in Files

Harvests ~/.ssh/*, ~/.env, ~/.npmrc, ~/.kube/config, and macOS Keychain entries. Detected by scan_secrets file access pattern matching.

T1552.005 Unsecured Credentials: Cloud Instance Metadata API

Queries IMDS at 169.254.169.254:80 to steal IAM role credentials and instance identity tokens. Detected by threat_model IMDS access pattern and check_mitre technique coverage.

T1071.001 Application Layer Protocol: Web Protocols

C2 communication over HTTPS to GitHub API IPs (20.205.243.168:443) and Cloudflare-fronted domain (162.159.36.12:443). Detected by threat_model network exfiltration analysis.

T1543.001 Create or Modify System Process: Launch Agent

Installs macOS LaunchAgent com.user.kitty-monitor.plist via launchctl bootout/bootstrap for persistence. Detected by Halo CDR ProcessMonitor at runtime.

T1041 Exfiltration Over C2 Channel

All stolen credentials transmitted to the same Cloudflare-fronted HTTPS endpoint used for C2. Single channel for both command and exfiltration. Detected by check_mitre exfiltration technique mapping.

Zfuzz MCP covers 6 of these 7 techniques through its combined toolset. Use check_mitre with any technique ID to verify detection coverage, get remediation guidance, and understand which Zfuzz tools provide protection at each layer. The only gap is T1195.001 at the registry level (account takeover prevention is the registry's responsibility) — but the effects of T1195.001 are caught immediately at the package analysis layer.


Lessons for Every Developer Using AI Agents

Mini Shai-Hulud is not an anomaly. It is a template. Supply chain attacks targeting npm packages will continue to increase in frequency and sophistication. The @antv compromise proves that even widely-used, well-maintained packages are one stolen credential away from becoming attack vectors. If your AI agent installs packages on your behalf — and it does — you need guardrails that operate before installation, not after.

  1. Never let your AI agent install packages without scanning first. The preinstall hook runs during npm install. If your agent installs a compromised package, the payload has already executed by the time you see the terminal output. Use scan_dependencies as the mandatory gate before any install command.
  2. Audit every preinstall/postinstall hook in your dependencies. Run npm query ':attr(scripts, [preinstall])' and npm query ':attr(scripts, [postinstall])' on your existing lockfile. Any package running shell commands, spawning child processes, or downloading binaries in lifecycle scripts should be investigated immediately.
  3. Use @zfuzz/mcp scan_dependencies before every npm install. The tool checks OSV.dev for CVEs, analyzes publisher history for recent changes, detects lifecycle hooks with shell execution, flags package size anomalies, and identifies newly-created transitive dependencies. A 2-second scan prevents a 2-week incident.
  4. Monitor for publisher changes on critical packages. Mini Shai-Hulud was detectable from npm registry metadata alone: the publisher account changed 3 days before the malicious version dropped. Automate alerts for publisher changes on your top 50 dependencies.
  5. Run scan_secrets on your codebase regularly. Credentials leak silently. A compromised package may have already harvested your .env or .npmrc tokens in a previous version. Run scan_secrets weekly across your entire project to detect any exposed credentials that need rotation.

Frequently Asked Questions

What was the Mini Shai-Hulud attack?
Mini Shai-Hulud was a supply chain attack disclosed by Microsoft Threat Intelligence on May 20, 2026. The threat actor compromised an @antv npm maintainer account and published malicious versions of popular visualization packages including @antv/g, @antv/g-canvas, and @antv/g-svg. The attack chain involved a ~499KB obfuscated payload delivered via preinstall hooks using bun as runtime, credential theft targeting GitHub PATs, OIDC tokens, AWS/STS credentials, SSH keys, kubeconfig, .env, .npmrc, and Slack/Stripe/Vault tokens, C2 exfiltration via GitHub API IPs and Cloudflare-fronted domains, IMDS metadata theft from cloud instances, and persistence via macOS LaunchAgents.
Could Zfuzz MCP have prevented the @antv compromise?
Yes. Zfuzz MCP would have blocked the Mini Shai-Hulud attack at 5 of 7 stages. The critical block occurs at stage 2 (malicious package publication) — before npm install ever completes. scan_dependencies detects the preinstall hook anomaly, publisher change, package size spike (12KB to 499KB), and the never-before-seen @antv/setup dependency. The AI agent refuses to install and recommends the last safe version. Stages 6 and 7 (C2/IMDS and persistence) are detected at runtime by threat_model, check_mitre, and Halo CDR. Only stage 1 (account takeover at the registry level) is outside IDE-level detection scope.
How does scan_dependencies detect compromised packages?
scan_dependencies uses three detection layers. First, real-time CVE lookup against OSV.dev for known vulnerabilities and security advisories. Second, lifecycle hook analysis that flags preinstall, postinstall, and prepare scripts containing shell execution (sh -c), binary downloads (curl, wget), or non-standard runtimes (bun run). Third, package anomaly detection that compares file sizes against the previous published version (a 12KB to 499KB jump is an immediate red flag), checks for publisher/maintainer account changes within the last 7 days, and identifies new transitive dependencies with zero dependents or recent creation dates. All three layers flagged @antv/g@6.1.14 independently.
What MITRE ATT&CK techniques does Mini Shai-Hulud use?
Mini Shai-Hulud employs 7 MITRE ATT&CK techniques: T1195.001 (Supply Chain Compromise: Compromise Software Dependencies), T1059.007 (Command and Scripting Interpreter: JavaScript), T1552.001 (Unsecured Credentials: Credentials in Files — targeting .env, .npmrc, SSH keys, kubeconfig), T1552.005 (Unsecured Credentials: Cloud Instance Metadata API — IMDS at 169.254.169.254), T1071.001 (Application Layer Protocol: Web Protocols — C2 over HTTPS), T1543.001 (Create or Modify System Process: Launch Agent — macOS persistence), and T1041 (Exfiltration Over C2 Channel). Zfuzz MCP provides detection coverage for 6 of these 7 techniques.