The New Face of Supply Chain Attacks: npm Malware Built for CI/CD and Cloud Compromise
Executive Summary
Upwind is tracking an active software supply chain campaign impacting multiple npm packages commonly used across developer tooling, frontend frameworks, CI/CD pipelines, and cloud-native application environments. We identified malicious payloads designed specifically to target CI/CD systems, cloud identities, GitHub credentials, npm publishing workflows, developer machines, and AI developer tooling. The campaign includes install-time execution, credential harvesting, GitHub Actions abuse, npm propagation, persistence mechanisms, destructive anti-response behavior, remote access capabilities, and multiple evasion techniques aimed at modern CI/CD security controls. As of May 19, 2026, 04:00 UTC, we identified approximately 1,948 public GitHub repositories associated with attacker exfiltration activity using the repeated signature:
niagA oG eW ereH :duluH-iahS
which reverses to:
Shai-Hulud: Here We Go Again
The campaign appears active, and additional affected packages or payload variants may continue to emerge.
Confirmed Malicious Packages
| Package | Version |
| jest-canvas-mock | 2.5.3, 2.6.3, 2.7.3 |
| echarts-for-react | 3.0.7, 3.1.7, 3.2.7 |
| size-sensor | 1.0.4, 1.1.4, 1.2.4 |
| jest-date-mock | 1.0.11, 1.1.11, 1.2.11 |
| @antv/g-math | 3.2.0, 3.3.0 |
| @antv/util | 3.4.11, 3.5.11 |
| timeago.js | 4.1.2, 4.2.2 |
| @antv/scale | 0.6.2, 0.7.2 |
| @antv/matrix-util | 3.1.4, 3.2.4 |
| @antv/path-util | 3.1.1, 3.2.1 |
| @antv/g-canvas | 2.3.0, 2.4.0 |
Additional suspicious npm releases remain under investigation.
Technical Breakdown
The campaign uses multiple execution paths, but the payload behavior is consistent across the variants we analyzed. At a high level, the malware executes during package installation, determines whether it is running in a valuable developer or CI/CD environment, harvests credentials, validates GitHub and cloud access, exfiltrates data, establishes persistence, and attempts to propagate through stolen publishing credentials and compromised repositories. We identified multiple payload variants with different hashes, obfuscation layers, bootstrap paths, and delivery mechanisms. The differences appear intentional and likely designed to reduce the effectiveness of static detections and signature-based analysis.
Delivery Methods
We identified two primary delivery patterns.
Direct Install Hook
Some packages execute the malicious payload directly during installation:
"scripts": {
"preinstall": "bun run index.js"
}
Copied
This causes arbitrary code execution during:
npm installCopied
before the developer imports or uses the package.
Other packages use a stealthier delivery method through optionalDependencies:
"optionalDependencies": {
"@antv/setup": "github:antvis/G2#dc3d62a2181beb9f326952a2d212900c94f2e13d"
}
Copied
The injected dependency then executes:
"prepare": "bun run index.js && exit 1"Copied
The && exit 1 behavior makes the dependency appear to fail while allowing npm installation to continue normally. By the time npm prints the warning, the payload has already executed successfully. We identified malicious orphan commits pushed to the legitimate antvis/G2 GitHub repository shortly before package publication. These commits were used as payload delivery points for both @antv/setup and @sap/setup.
Payload Architecture
Across variants, the malware follows a consistent high-level execution flow:
npm install affected package
↓
preinstall / prepare hook executes
↓
bun run index.js
↓
environment and sandbox checks
↓
detached daemon process starts
↓
credential harvesting from env vars, files, GitHub CLI, and CI memory
↓
GitHub token validation and prioritization
↓
cloud, Kubernetes, Vault, npm, and SSH credential collection
↓
encrypted exfiltration to attacker infrastructure
↓
fallback exfiltration through GitHub repositories
↓
persistence through Claude / VS Code / system services
↓
possible npm propagation through stolen publish tokens
Copied
We observed several distinct payload binaries and obfuscation variants with similar functionality. The differences in payload size and hashes appear intentional and likely designed to reduce static signature effectiveness and complicate detection engineering.
Credential Harvesting
The malware collects credentials from several sources in parallel.
Environment Variables
The payload dumps the full environment and specifically targets high-value variables, including:
- GITHUB_TOKEN
- ACTIONS_ID_TOKEN_REQUEST_URL
- ACTIONS_ID_TOKEN_REQUEST_TOKEN
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN
- VAULT_TOKEN
- KUBECONFIG
GitHub Actions OIDC material is especially sensitive because it may allow attackers to impersonate GitHub Actions workloads to cloud providers that trust GitHub federation.
Filesystem Secrets
The malware scans developer and CI systems for SSH keys, .npmrc tokens, AWS, GCP, and Azure credentials, Kubernetes configs, Docker credentials, Terraform credentials, Vault configs, Git credentials, .env files, shell history, cryptocurrency wallets, messaging application artifacts, and AI tooling credentials. Notably, the malware targets Claude-related configuration files:
~/.claude.json
~/.claude/mcp.json
Copied
This suggests the attackers understand that AI developer tools increasingly store sensitive API keys, MCP server configurations, and third-party service credentials.
GitHub CLI Tokens
The malware invokes the GitHub CLI to retrieve authenticated GitHub session tokens, then validates them through the GitHub API.
Password Manager and Secret Store Collection
We identified collection logic targeting multiple password managers and secret stores. The malware attempts to extract data from 1Password, Bitwarden, Pass, and Gopass, including full vault contents where the required access material is available. It also targets HashiCorp Vault through multiple authentication paths, including environment tokens, token files, Kubernetes service account JWTs, and AWS IAM-based auth. Once authenticated, the malware attempts to enumerate KV mounts and dump KV v1 and KV v2 secrets.
Cloud and Kubernetes Secret Dumping
The malware does not stop at local credential files. We identified AWS collection logic that attempts to validate credentials with STS, enumerate Secrets Manager secrets, and retrieve SSM Parameter Store values with decryption across multiple AWS regions. Kubernetes collection logic targets both in-cluster service account tokens and workstation kubeconfigs, lists namespaces, and attempts to dump secrets from user namespaces. This makes the campaign especially dangerous in CI/CD and cloud-native environments where a single runner or developer workstation may hold access to multiple production systems.
GitHub Token Validation and Abuse
We identified logic that actively validates discovered GitHub tokens through:
https://api.github.com/user
https://api.github.com/user/orgs
Copied
The malware checks whether tokens are valid, what scopes they have, whether they belong to personal or organization accounts, and whether they include repo or workflow permissions. Tokens with repository and workflow access are prioritized because they can be used for repository modification, workflow manipulation, exfiltration through GitHub commits, backdooring repositories, and malware propagation.
GitHub Actions Memory Dumping
One of the more advanced capabilities identified is GitHub Actions memory dumping. When running inside Linux GitHub Actions environments, the malware attempts to locate the Runner.Worker process, read /proc/<pid>/maps, dump readable memory regions from /proc/<pid>/mem, and extract GitHub Actions secrets and runner tokens from memory. We also identified cross-platform memory dumping logic for Linux, macOS, and Windows using platform-specific APIs. This behavior is important because it attempts to recover secrets that may already be loaded into memory, bypassing normal secret masking protections.
Exfiltration Architecture
The primary exfiltration channel uses HTTPS POST requests to attacker-controlled infrastructure disguised as an OpenTelemetry endpoint:
https://t.m-kosche.com/api/public/otel/v1/tracesCopied
The path resembles legitimate telemetry ingestion traffic, which may help it blend into environments where observability traffic is expected. The malware also spoofs the User-Agent:
python-requests/2.31.0Copied
even though the payload executes through JavaScript/Bun. When direct C2 exfiltration is skipped or unavailable, the malware falls back to GitHub-based exfiltration by committing stolen data into attacker-created repositories as JSON files.
Persistence Through Developer Tooling
We identified persistence mechanisms targeting developer workflows. The malware copies itself into Claude or Codex-related directories and modifies developer tool configuration files so it re-executes when a Claude Code session starts, a repository is opened, or VS Code tasks are triggered. Observed persistence artifacts include:
~/.claude/package/index.js
.claude/settings.json
.vscode/tasks.json
Copied
This means removing the original npm package may not be enough. The malware can survive through modified developer tooling configuration.
Repository Backdooring
When valid GitHub tokens are available, the malware can inject files directly into victim repositories. Observed injected files include:
.claude/index.js
.claude/setup.mjs
.claude/settings.json
.vscode/tasks.json
Copied
Anyone who later clones or opens the infected repository with supported tooling may re-trigger the payload.
GitHub Actions Secret-Dumping Workflow
We identified injected GitHub Actions workflow logic designed to dump repository secrets into an artifact. The workflow is deployed under a path such as:
.github/workflows/codeql.ymlCopied
and uses a workflow name designed to blend in:
Run CopilotCopied
The workflow writes toJSON(secrets) into an artifact named:
format-resultsCopied
The workflow also uses pinned action references that appear to be attacker-controlled forks rather than official GitHub Actions. The newer analysis also shows a two-stage inject-and-cleanup process: the malware can commit the workflow, wait for it to run, download the artifact, delete the workflow run, and force-reset the branch back to its original state. This is designed to collect secrets while removing evidence from repository history.
Remote Access Trojan Behavior
We identified an additional persistence capability using a kitty-monitor service. This component installs a Python script at:
~/.local/share/kitty/cat.pyCopied
and registers it as a persistent background service. The service searches GitHub commits for the keyword:
firedalazerCopied
When a signed command is found, it verifies the payload with an attacker-controlled RSA key, downloads code from the referenced URL, and executes it. This gives the attacker a long-term command channel that can survive npm package removal and does not require a traditional C2 domain to remain active. We also identified a second GitHub dead-drop resolver keyword:
thebeautifulmarchoftimeCopied
used to discover alternate C2 infrastructure through signed GitHub commit messages.
Docker Privilege Escalation and Security Tool Neutralization
We identified Docker-aware behavior intended to weaken CI/CD defenses. In Docker-enabled GitHub Actions environments, the malware can query the Docker socket, identify containers associated with security tooling such as StepSecurity Harden-Runner, and attempt to terminate them. Additional logic uses a privileged container with a host bind mount to write a sudoers file granting passwordless sudo to the runner user. The malware can then poison /etc/hosts to block StepSecurity domains such as agent.stepsecurity.io, api.stepsecurity.io, and app.stepsecurity.io, preventing monitoring infrastructure from receiving telemetry.
npm Propagation Behavior
The malware includes npm worm-like propagation logic. We identified two propagation paths. In the PAT-based path, when a .npmrc or npm token with publishing permissions is found, the malware can inject itself into packages, add a postinstall hook, add a malicious optional dependency, and republish poisoned packages. In the OIDC-based path, when GitHub Actions OIDC material is available, the malware can exchange the OIDC token for npm publishing access, inject @sap/setup, bump the minor version, and publish a new compromised release. One observed propagation dependency was:
@sap/setupCopied
pointing to:
github:antvis/G2#1916faa365f2788b6e193514872d51a242876569Copied
This can turn one compromised developer or CI environment into a new distribution point for downstream compromise.
Destructive and Extortion Behavior
Some variants include destructive anti-response behavior. We identified a token-monitoring service that checks whether stolen GitHub tokens remain valid. If a token is revoked or certain package-state canaries change, the malware may execute destructive commands against the victim’s home directory. The payload includes the hardcoded message:
IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwnerCopied
This means defenders should be careful during response. If persistence artifacts are present, persistence components should be removed before revoking affected GitHub tokens.
Security Tool Evasion
The attackers appear to be actively designing around common CI/CD security tools and incident response workflows.
Observed evasion and anti-analysis techniques include:
- StepSecurity Harden-Runner detection
- References to:
agent.stepsecurity.ioapi.stepsecurity.ioapp.stepsecurity.io
- Docker-based security tool neutralization
- Decoy GitHub token detection
- Daemonized detached execution
- Singleton lock files
- Signal handler suppression
- Multiple obfuscation variants
- Payload hash variation across samples
- Encrypted C2 configuration details
- OpenTelemetry-style network camouflage
- GitHub-based fallback exfiltration infrastructure
- Russian locale bypass logic
The Russian locale bypass is especially notable because the malware skips execution when certain Russian locale indicators are present. This pattern is commonly observed in malware families attempting to avoid activity in specific jurisdictions and may provide attribution-relevant signals.
Designed to Spread, Persist, and Fight Back
What makes this campaign stand out is how defender-aware it is.
The malware does not simply execute and steal credentials. It checks where it is running, looks for security tooling, validates whether stolen tokens are valuable, varies payload hashes, encrypts sensitive strings, hides traffic behind telemetry-like endpoints, persists through developer tools, uses GitHub itself as both an exfiltration and command channel, and attempts to erase evidence after abusing GitHub Actions workflows.
We identified capabilities targeting nearly every layer of the modern developer pipeline, including CI/CD systems, GitHub Actions runners, npm publishing workflows, cloud credentials, Kubernetes secrets, local developer environments, AI developer tooling such as Claude Code, password managers, Vault, AWS Secrets Manager, SSM Parameter Store, and containerized CI/CD infrastructure. This was not typical smash-and-grab npm malware. It behaved more like a modern intrusion framework delivered through trusted package installation workflows – designed not only to steal secrets, but to persist, propagate, evade defenders, and turn compromised developer environments into new distribution points.
GitHub Became the Exfiltration Infrastructure
We identified approximately 1,948 public GitHub repositories associated with attacker exfiltration activity as of May 19, 2026, 04:00 UTC. These repositories appear to have been created automatically using stolen GitHub credentials and share the same description string:
niagA oG eW ereH :duluH-iahSCopied
We identified several compromised GitHub accounts associated with this activity, including early victim activity dating back to May 16. Observed victim activity included earliest known victim activity on May 16, SAP-linked activity on May 18, rapid repository creation bursts on May 19, and automated creation of dozens of repositories within minutes from individual accounts. This indicates the campaign was already active before the most visible npm package publications and had begun using stolen GitHub accounts as exfiltration infrastructure.
Linked SAP Package Activity
We identified a linked attack involving:
@cap-js/[email protected]Copied
The package appears to have been published using a compromised cap-npm npm account associated with SAP’s Cloud Application Programming Model ecosystem.
Key Findings
@cap-js/[email protected]was published on May 18, 2026.- The package appears to have been published directly using a stolen npm personal access token (PAT).
- The release did not follow the normal GitHub Actions OIDC publishing flow used by legitimate releases.
- The malicious version was later yanked.
- A clean
@cap-js/[email protected]was published at12:36:23 UTCthrough GitHub Actions OIDC. - SAP’s open source security team account was added as maintainer during recovery.
- No corresponding GitHub Actions run was identified for
1.4.1, while legitimate releases from1.3.0onward consistently used OIDC.
The use of a PAT instead of OIDC is a strong indicator that the cap-npm publishing account was compromised and abused directly.
The malware also hardcoded @cap-js/[email protected] as a dead-man-switch canary. If the package was removed or deprecated, the malware could trigger destructive behavior on infected systems.
This strongly suggests the attackers were monitoring defender response and using package state as a signal for whether victims had detected the compromise.The later a2ed1d59 commit appears to be a post-remediation workflow improvement, not a failed recovery attempt.
Campaign Timeline
| Time | Event |
| 2026-05-16 06:10 UTC | Earliest confirmed GitHub exfil victim activity observed |
| 2026-05-18 11:49 UTC | @cap-js/[email protected] published via compromised cap-npm PAT, bypassing OIDC |
| 2026-05-18 12:25 UTC | SAP-linked GitHub exfil repositories begin appearing |
| 2026-05-18 12:36 UTC | Clean @cap-js/[email protected] published via GitHub Actions OIDC |
| 2026-05-18 12:47 UTC | SAP adds workflow_dispatch trigger in post-remediation commit a2ed1d59 |
| 2026-05-19 01:25 UTC | Malicious orphan commit 1916faa3… pushed to antvis/G2 |
| 2026-05-19 01:47 UTC | Malicious orphan commit dc3d62a2… pushed to antvis/G2 |
| 2026-05-19 01:49 UTC | [email protected] published |
| 2026-05-19 01:56 UTC | [email protected] published |
| 2026-05-19 03:41 UTC | Rapid exfil repository creation observed from victim account |
| 2026-05-19 04:00 UTC | Approximately 1,948 GitHub exfil repositories identified |
Indicators of Compromise (IOCs)
Indicators of Compromise (IOCs)
| Type | Value | Notes |
| C2 Domain | t.m-kosche.com | Block at egress |
| C2 URL | https://t.m-kosche.com/api/public/otel/v1/traces | Spoofed OpenTelemetry endpoint |
| C2 Port | 443 | HTTPS |
| User-Agent | python-requests/2.31.0 | Spoofed from JS/Bun process |
| GitHub API | https://api.github.com | Used for token validation and fallback exfil |
| Exfil Repo Signature | niagA oG eW ereH :duluH-iahS | Reversed Shai-Hulud message |
| Total Exfil Repos | 1,948+ | As of 2026-05-19 04:00 UTC |
| Threat Actor GitHub | Alexzjt / huiyu.zjt | Associated with malicious commits |
| Commit Message | New Package | Used on malicious commits |
| GitHub Commit | dc3d62a2181beb9f326952a2d212900c94f2e13d | @antv/setup entry point |
| GitHub Commit | 1916faa365f2788b6e193514872d51a242876569 | @sap/setup propagation payload |
| PID Lock File | $TMPDIR/tmp.0987654321.lock | Active infection marker |
| Env Marker | __DAEMONIZED=1 | Detached process marker |
| Payload Runtime | bun | Installed as dependency |
| Payload File | index.js | ~486 KB obfuscated payload |
| Persistence Script | ~/.local/bin/gh-token-monitor.sh | Token monitor / wipe trigger |
| Persistence Dir | ~/.config/gh-token-monitor/ | Stores stolen token and handler |
| macOS Persistence | ~/Library/LaunchAgents/com.user.gh-token-monitor.plist | Token monitor service |
| Linux Persistence | ~/.config/systemd/user/gh-token-monitor.service | Token monitor service |
| Claude Hook Payload | ~/.claude/package/index.js | Malware copy |
| RAT Script | ~/.local/share/kitty/cat.py | kitty-monitor RAT |
| RAT State File | /var/tmp/.gh_update_state | Tracks executed commands |
| RAT macOS Persistence | ~/Library/LaunchAgents/com.user.kitty-monitor.plist | RAT persistence |
| RAT Linux Persistence | ~/.config/systemd/user/kitty-monitor.service | RAT persistence |
| RAT C2 Keyword | firedalazer | GitHub commit search keyword |
| Alt C2 Keyword | thebeautifulmarchoftime | GitHub commit search keyword |
| Injected Workflow Path | .github/workflows/codeql.yml | Fake CodeQL workflow path |
| Injected Workflow Name | Run Copilot | Suspicious workflow name |
| Injected Workflow Branch | chore/add-codeql-static-analysis | Temporary branch used for workflow injection |
| Injected Workflow Commit | fix: ci | Blending commit message |
| Actions Artifact | format-results | Secret dump artifact |
| Pinned Checkout | actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd | Attacker fork |
| Pinned Upload Artifact | actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f | Attacker fork |
| Alternate Script | router_runtime.js | Alternate bootstrap path |
| Alternate Script | ai_init.js | Alternate bootstrap path |
| Encryption Key | 49d3f75bfb90c9708c7db7f16d60e6e76e4fcddd14c98c5bde68f8fb4ab903ed | Payload string encryption |
| Encryption Salt | 8d91f1541f7c152a84e6b640b0f278a9 | Payload string encryption |
Recommendations
Organizations should immediately:
- Avoid installing or upgrading affected package versions.
- Review package installation logs for suspicious
preinstall,postinstall, orprepareexecution. - Investigate unexpected
bunexecution during npm package installation. - Block outbound traffic to
t.m-kosche.com. - Search GitHub for repositories containing the signature
niagA oG eW ereH :duluH-iahS. - Inspect repositories for injected
.claude,.vscode, and suspicious GitHub Actions workflow files. - Audit GitHub Actions workflows for unauthorized secret-dumping behavior or unexpected workflow changes.
- Review npm publishing history for unexpected releases or modified package metadata.
- Rotate exposed cloud credentials, GitHub tokens, npm publishing tokens, SSH keys, Vault tokens, and AI tooling credentials.
- Audit Kubernetes, Helm, Terraform, Docker, Vault, password manager, AWS Secrets Manager, and SSM exposure.
- Inspect developer workstations and CI/CD runners for persistence artifacts, detached
bunprocesses, and unauthorized background services. - Review Docker-enabled CI/CD environments for suspicious privileged container activity or tampering with security tooling.
Important: if gh-token-monitor persistence is present, remove the persistence components before revoking GitHub tokens to avoid triggering destructive behavior on infected systems.
Host Cleanup
Check and remove the following artifacts where present:
~/.local/bin/gh-token-monitor.sh
~/.config/gh-token-monitor/
~/Library/LaunchAgents/com.user.gh-token-monitor.plist
~/.config/systemd/user/gh-token-monitor.service
~/.claude/package/index.js
.claude/settings.json
.vscode/tasks.json
$TMPDIR/tmp.0987654321.lock
~/.local/share/kitty/cat.py
/var/tmp/.gh_update_state
~/Library/LaunchAgents/com.user.kitty-monitor.plist
~/.config/systemd/user/kitty-monitor.service
Copied
How Upwind Can Help
Upwind helps organizations detect and investigate supply chain attacks at runtime, where malicious package behavior actually executes. In this campaign, the malware abused package installation workflows, spawned detached processes, harvested credentials from developer and CI/CD environments, accessed GitHub and cloud identities, communicated with attacker infrastructure, attempted to neutralize security tooling, and persisted through developer workflows. Much of this behavior may not be visible from static dependency scanning alone.
Upwind can help identify suspicious install-time execution such as preinstall and prepare lifecycle abuse, unexpected bun execution during package installation, credential access targeting .npmrc, .env, SSH keys, kubeconfigs, cloud credential stores, Vault tokens, GitHub Actions material, password managers, and containerized CI/CD secrets, suspicious GitHub workflow changes, unexpected outbound communication to attacker-controlled infrastructure, runtime persistence behavior, Docker socket abuse, security tool tampering, and potential propagation from compromised CI/CD runners or developer environments.
By correlating runtime process activity, network behavior, identity context, cloud access, package execution, and workload telemetry, Upwind helps security teams determine whether an affected package was merely present or actually executed, which credentials may have been exposed, what systems were impacted, and where containment should begin.


