Back to Feed
HIGH Supply Chain Published Supply Chain

AntV Mini Shai-Hulud Technical Analysis: npm Publish Abuse and CI Secret Theft

Technical teardown of the May 19 AntV npm wave, covering publish-right abuse, optional GitHub dependency droppers, Bun lifecycle execution, secret theft, persistence, and exfiltration.

May 22, 2026, 1:39 AM May 22, 2026, 1:39 AM High confidence

Affected ecosystems: npm

5 Assets
10 IOCs
2 Rules
3 Sources

Executive Summary

On May 19, 2026, a series of malicious npm packages were published under the AntV namespace and related projects. The attack involved compromised publication rights, used to inject malicious lifecycle scripts and optional GitHub dependencies that executed credential-stealing payloads. The campaign targeted developer and CI environments, specifically seeking GitHub, npm, and cloud credentials.

Analyst Assessment

This incident is part of the Mini Shai-Hulud family. The use of optional dependencies pointing to GitHub commit refs and the use of the Bun runtime for payload execution are key technical signatures. The attack appears highly automated, leveraging stolen maintainer tokens to perform a wide sweep of the AntV ecosystem.

Impact

Affected environments face immediate risk of credential theft (GitHub, npm, AWS, Vault, Kubernetes). The payload also establishes persistence via developer tool configurations (.vscode, .claude), allowing for long-term access and potential downstream supply chain propagation.

Exploitation Status

Active exploitation was observed during a tight window on May 19, 2026. Registry cleanup has since occurred, but affected versions may still exist in local caches, lockfiles, or internal mirrors.

Defender Guidance

Immediately audit lockfiles for '@antv/setup' or GitHub dependency refs under 'antvis/G2'. Inspect projects for unexpected .claude or .vscode configuration changes. Rotate any secrets (npm, GitHub, Cloud) that were present in environments where affected packages were resolved or executed.

Technical Analysis

Attack Overview

The May 19, 2026, supply chain attack targeting the AntV ecosystem represents a sophisticated escalation in the "Mini Shai-Hulud" campaign family. This wave specifically targeted high-profile data visualization and utility packages within the npm registry, including echarts-for-react, size-sensor, and jest-canvas-mock. Unlike simpler "dependency confusion" attacks, this campaign leveraged compromised maintainer credentials—specifically the atool account—to inject malicious logic directly into established, trusted packages. The scope of the attack was broad, affecting over 300 package versions in a coordinated burst. The primary goal was the systematic exfiltration of developer and CI/CD secrets, including GitHub tokens, npm credentials, and cloud service metadata, effectively turning the build pipelines of thousands of downstream users into credential-harvesting engines.

Step-by-Step Execution

The attack followed a precise multi-stage progression designed to maximize reach and minimize immediate detection:

  1. Initial Access: Attackers gained control of npm publication rights, likely through a stolen automation token or a compromised session belonging to the atool maintainer.
  2. Ghost Dependency Injection: Affected packages were updated to include @antv/setup as an optional dependency. Crucially, this dependency was not resolved from the npm registry but instead pointed directly to specific git commit hashes on GitHub (e.g., github:antvis/G2#7cb42...).
  3. Execution: When a user installed an affected package, the optional dependency was fetched. The malicious @antv/setup package utilized Bun-based lifecycle hooks (prepare or preinstall) to execute an obfuscated index.js payload.
  4. Secret Harvesting: The payload performed an exhaustive search of the environment. It targeted .gitconfig, .npmrc, AWS metadata endpoints (169.254.169.254), and environment variables containing "GITHUB_", "NPM_", or "VAULT_".
  5. Memory Scraping: In GitHub Actions environments, the malware utilized advanced techniques to scrape the runner's memory for ephemeral OIDC tokens and transient secrets that aren't stored on disk.
  6. Persistence: The malware attempted to inject code into local developer tool configurations, such as .claude/settings.json and .vscode/tasks.json, ensuring that the payload would be re-triggered whenever the developer opened the project or started a new session.
  7. Exfiltration: Data was bundled and sent to attacker-controlled infrastructure at t.m-kosche.com via HTTPS requests disguised as OpenTelemetry traces, or through the decentralized Session network to avoid IP-based blocking.

Code-Level Mechanics

The core of the "Ghost Dependency" trick is found in the package.json of the compromised packages. By using optionalDependencies, the attacker ensures that the installation won't fail if the malicious repo is taken down, making the attack more resilient.

"optionalDependencies": {
  "@antv/setup": "github:antvis/G2#7cb42f57561c321ecb09b4552802ae0ac55b3a7a"
}

The payload execution is driven by the Bun runtime, which is increasingly common in modern frontend toolchains but often less scrutinized than standard Node.js scripts in security audits. The use of prepare: bun run index.js && exit 1 is a clever "fail-open" strategy; the nonzero exit code prevents the dependency from appearing as successfully "installed" in some logs, while the side effects (credential theft) have already occurred.

Payload Behavior

Once active, the index.js payload is highly aggressive. It doesn't just look for files; it scans the process environment and active network connections. It specifically looks for CI/CD identifiers to adjust its behavior, becoming more stealthy in developer machines while performing loud, broad sweeps in automated build runners. The use of python-requests/2.31.0 for some API interactions indicates a modular approach where different components are fetched or triggered based on the host environment's capabilities.

Detection Opportunities

Defenders should prioritize auditing their dependency trees for any references to GitHub commit hashes, particularly those within the @antvis organization. Standard npm audit tools may miss these if the root package isn't considered "vulnerable" in the public database yet.

  1. Log Analysis: Search for outbound traffic to t.m-kosche.com or filev2.getsession.org.
  2. Configuration Monitoring: Check for unauthorized changes to .vscode/tasks.json or .claude/settings.json.
  3. Runtime Protection: Implement egress filtering in CI/CD environments to block all non-essential outbound connections, particularly to unknown domains.

Evidence Gaps

While the technical execution is well-understood, several gaps remain. The exact method used to compromise the atool account is still under investigation; it is unclear if this was a result of a password reuse, a phishing attack, or a breach of a third-party service with broad npm permissions. Additionally, the full list of secrets exfiltrated from specific organizations is unknown, though the targeting suggests a high level of interest in cloud infrastructure and private source code repositories.

Indicators of Compromise (IOCs)

Type Indicator Example Notes
Package npm @antv/g2 Affected: 5.5.8, 5.6.8
Package npm @antv/l7-core Affected: 2.26.10, 2.27.10
Package npm echarts-for-react Affected: 3.0.7
Package npm jest-canvas-mock Affected: 2.5.3
Package npm size-sensor Affected: 1.0.4, 1.1.4, 1.2.4
url Network IOCs filev2.getsession.org/file/ Exfiltration route via Session network
url Network IOCs github:antvis/G2#1916faa365f2788b6e193514872d51a242876569 Malicious optional dependency ref used in jest-canvas-mock
url Network IOCs github:antvis/G2#7cb42f57561c321ecb09b4552802ae0ac55b3a7a Malicious optional dependency ref used in echarts-for-react and size-sensor
domain Network IOCs t.m-kosche.com Exfiltration domain mimicking OpenTelemetry traffic
hash File, Path, Config, and Hash Artifacts a68dd1e6a6e35ec3771e1f94fe796f55dfe65a2b94560516ff4ac189390dfa1c SHA-256 of obfuscated index.js payload reported in @antv/l7-core

Detection Opportunities

AntV Setup Phantom Dependency

lockfile_audit
Audit lockfiles for '@antv/setup' pointing to github:antvis/G2 commit refs.

False positives: None known for this specific pattern in these packages.

Mini Shai-Hulud Bun Lifecycle Execution

yara
rule MiniShaiHulud_Bun_Lifecycle { strings: $s1 = "\"prepare\": \"bun run index.js && exit 1\"" $s2 = "\"preinstall\": \"bun run index.js\"" condition: any of them }

False positives: Legitimate use of Bun in scripts is possible but rare in these specific AntV packages.

Timeline

incident_start

jest-canvas-mock 2.5.3 published to npm registry (01:39:31Z)

propagation

size-sensor 1.0.4 published (01:44:36Z)

propagation

echarts-for-react 3.0.7 published (01:47:12Z)

propagation

Broader AntV batches observed around 02:05Z/02:06Z

Intelligence Sources