Back to threat alerts

Supply Chain Worm Campaign Updates (Miasma, TeamPCP, & VS Code Exploit)

Threat actors have officially moved beyond basic "nuisance" typosquatting through deploying sophisticated, automated, and self-propagating worms targeting trusted namespaces. By subverting continuous integration (CI/CD) pipelines and developer IDEs, they have turned the very systems designed to build and secure our code into automated distribution nodes. Recent threat landscape is dominated by TeamPCP and the Shai-Hulud worm, a self-propagating payload is engineered to steal publishing credentials, enumerate every package accessible to those credentials, inject malicious logic, and republish backdoor versions automatically.

Threat alert
June 3, 2026
Chronology of the 2026 Pipeline Hijackings
Date Target / Campaign Core Mechanism Malware Family Key Indicator
Feb 28 Aqua Trivy & PyPI LiteLLM GitHub Actions privilege escalation Early Shai-Hulud & sysmon.py Canister traffic; typosquatted domains
Apr 22 @bitwarden/cli npm Poisoned GHA release workflow "Shai-Hulud: The Third Coming" Platform-detecting loaders
Apr 29 SAP npm & @cap-js npm token leaked via CircleCI pull request Shai-Hulud Core Outbound exfiltration to dead-drops
Apr 30 PyTorch Lightning (PyPI) Automated PyPI account hijacking Shai-Hulud Core Malicious releases v2.6.2 & v2.6.3
May 11 TanStack, Mistral AI, Guardrails AI PR cache poisoning; GHA OIDC runtime memory theft Mini Shai-Hulud 84 malicious npm packages
May 12 Open Source Leak Full source code leaked on BreachForums Mini Shai-Hulud Weaponized worm code publicly available
May 18 Nx Console (VS Code Extension) Contributor token abuse; orphan Git commits Mini Shai-Hulud ~6,000 silent extension activations
May 19 @antv / atool Burst Compromised npm account; 637 malicious versions Mini Shai-Hulud 22-minute automated publish storm
May 19 Microsoft DurableTask Stolen GitHub personal access token Mini Shai-Hulud Compromised Python SDK release cycle
Jun 1 @redhat-cloud-services Compromised employee GitHub account Miasma ("The Spreading Blight") 32 compromised packages; cloud mappings

Deconstructing the TanStack CI/CD Exploit

In the May 11 TanStack compromise attackers chained three distinct pipeline weaknesses to publish malicious packages bearing valid, cryptographically signed Level 3 SLSA (Software Artifacts Source Aligned) provenance.

  • The Trigger Bypass: The attacker forked the public TanStack/router repository, naming it zblgg/configuration to evade fork-monitoring tools. They authored a malicious commit (65bf499d) using a fabricated identity <[email protected]> to mimic the official Anthropic Claude app, and prefixed the commit with [skip ci] to bypass push-event checks.
  • The Trigger Exploitation: They opened pull request #7378, triggering TanStack's bundle-size.yml workflow. Because the workflow used the privileged pull_request_target trigger but explicitly checked out the untrusted fork's merge ref, the attacker's code executed directly within the security context of the base repository, gaining write access to secrets and tokens.
  • Cache Poisoning: The malicious script (vite_setup.mjs) did not steal secrets immediately. Instead, it targeted the GitHub Actions build-cache system. Since cache writes use a runner-internal token that is completely unaffected by user-defined read-only permissions, the script modified the local pnpm store.

Memory Extraction & OIDC Abuse

On May 11, a legitimate release run pulled and restored the poisoned cache. When the build process initiated tanstack_runner.js, the payload extracted the short-lived OpenID Connect (OIDC) identity token directly from the process memory of the active GitHub Actions runner daemon (Runner.Worker) by reading /proc/<pid>/mem.

Using this OIDC token, the malware sent direct HTTP POST requests to registry.npmjs.org. Since publishing went through the official runner, Sigstore generated valid Level 3 SLSA provenance certificates. Over a six-minute window, the attackers successfully published 84 malicious versions across 42 @tanstack/* packages.

The Nx Console Extension Hijack

Using a GitHub personal access token stolen during the TanStack compromise, the attackers gained write access to the nrwl/nx monorepo.

  • To avoid code-review pipelines, they pushed an orphan commit (a commit with no parent or connection to repository history) containing only a malicious package.json and index.js.
  • They published Nx Console version 18.95.0 to the Visual Studio Marketplace, referencing the orphan commit via a hardcoded SHA.
  • VS Code's silent auto-update pushed the extension to approximately 6,000 developer workstations.
June 2026: The Red Hat "Miasma" Wave

On June 1, 2026, the attackers targeted the @redhat-cloud-services npm namespace. An attacker compromised a Red Hat employee's GitHub account and pushed malicious orphan commits directly to two RedHatInsights repositories. The commits launched a minimal GitHub Actions workflow that requested an OIDC token and published 32 compromised packages.

The payload was identified as a descendant of the Mini Shai-Hulud worm dubbed Miasma. Crucially, Miasma added cloud control plane enumeration engine capabilities, scanning infected systems for active cloud CLI environments and querying GCP/Azure metadata endpoints to hijack broader cloud-hosted infrastructure.

To bypass network monitoring tools that flag traffic to known malicious domains, Miasma uses a highly resilient exfiltration loop. The malware programmatically generates public repositories directly on the victim's own hijacked GitHub accounts. These repositories are assigned distinct descriptions and host the RSA-encrypted exfiltration payloads. If direct token publishing fails, the worm falls back to posting double-Base64-encoded exfiltration payloads within commit messages carrying the signature "OhNoWhatsGoingOnWithGitHub:".

The VS Code Sandboxed Webview Zero-Day

In June 2026, computer scientist Ammar Askar disclosed an unpatched 1-click zero-day vulnerability in the VS Code sandboxed webview message-passing system on github.dev. It allows attackers to steal a user’s unscoped GitHub OAuth token, granting full access to all the victim's public and private repositories—simply by tricking them into clicking a link.

When a user works on github.dev, github.com POSTs an OAuth token to the web editor. Because this editor runs in the browser, sandboxed webviews (for Markdown or Jupyter previews) are isolated in <iframe> tags hosted on a separate origin (vscode-webview://...) to prevent malicious script execution. However, to keep keyboard shortcuts functional, webviews listen for keydown events inside the iframe and bubble them up to the main editor via a serialized did-keydown postMessage.

As the main window did not verify if these events were physically typed by a human, an untrusted script in a webview could programmatically synthesize keypresses.

The Exploit Path

To bypass security confirmation dialogs and achieve full execution, the exploit orchestrated a precise bypass sequence:

  • Accepting Notifications: Programmatically dispatches Ctrl + Shift + A to auto-click the primary action on VS Code notifications.
  • Abusing Trusted Workspaces: Places local recommended extensions inside .vscode/extensions (which run automatically on github.dev without publisher trust warnings).
  • Bypassing Content Security Policy (CSP): The local extension's package.json registers custom keybindings. It maps Ctrl + F1 to execute workbench.extensions.installExtension with skipPublisherTrust: true.
  • The Kill: When a user opens a repository containing a Jupyter notebook (.ipynb) with an HTML injection payload (such as <img src="data:foobar" onerror="payload();">), the payload simulates the keystroke chain, installs a hosted malicious extension, harvests the victim's unscoped GitHub OAuth token, and exfiltrates it.
  • Workaround: Users can protect themselves by clearing cookies and local site data for github.dev in their browsers. This forces an explicit sign-in and warning prompt when an extension attempts to authorize with GitHub.

Incident Response Recommendations

If any of your developer systems, build environments, or CI/CD pipelines ran an npm install resolving to the compromised @redhat-cloud-services versions (June 1) or @tanstack versions (May 11), follow this exact order of operations to prevent system data destruction.

Neutralise the Dead Man's Switch

Do not rotate credentials immediately. If the background daemon detects token revocation, it will trigger a home directory wipe (rm -rf ~/*). Run the following commands to stop and disable the persistence mechanisms first:

# On Linux Systems: Stop and disable the malicious systemd services
systemctl --user stop gh-token-monitor.service kitty-monitor.service sysmon.service pgmon.service 2>/dev/null
systemctl --user disable gh-token-monitor.service kitty-monitor.service sysmon.service pgmon.service 2>/dev/null

# On macOS Systems: Unload the malicious Launch Agents
launchctl unload ~/Library/LaunchAgents/com.user.kitty-monitor.plist 2>/dev/null
launchctl unload ~/Library/LaunchAgents/com.user.gh-token-monitor.plist 2>/dev/null
rm -f ~/Library/LaunchAgents/com.user.*.plist

Step 2: Audit & Cleanse Workspaces

Ensure the worm has not planted persistent hooks in local development tools:

  • Open and inspect ~/.claude/settings.json and .claude/settings.json for suspicious SessionStart hooks mapping to setup.mjs or router_runtime.js.
  • Inspect .vscode/tasks.json for unauthorised folderOpen tasks.
  • Audit your Git configuration and commit histories for unauthorised commits authored by the spoofed identity: claude <[email protected]>.

Step 3: Clean Package Directories

Wipe the compromised caches and dependencies directly from disk:

# Force clear local dependencies
rm -rf node_modules
rm -rf ~/.npm/_cacache
rm -rf ~/.local/share/pnpm/store

# Reinstall using known-clean versions in package.json
npm install --ignore-scripts

Step 4: Securely Rotate Credentials

Once local persistence is fully neutralised, rotate all potentially exposed secrets from a known-clean machine in this priority order:

  1. npm publish tokens and OIDC federation grants.
  1. GitHub Personal Access Tokens (PATs) and SSH private keys.
  1. Cloud provider credentials (AWS, GCP, Azure access keys and instance roles).
  1. HashiCorp Vault tokens and Kubernetes service account tokens.
Indicators of Compromise (IoCs)
Artifact Type Indicator Value Context
Directory Path ~/.local/share/kitty/cat.py Python-based C2 backdoor client
Systemd Service ~/.config/systemd/user/kitty-monitor.service Linux background persistence daemon
LaunchAgent ~/Library/LaunchAgents/com.user.kitty-monitor.plist macOS background persistence agent
User-Agent String google-api-nodejs-client/7.0.0 gl-node/20.11.0 gccl/7.0.0 User-Agent used by Miasma to scan GCP metadata
Repo Description "Miasma: The Spreading Blight" Explored/created public GitHub exfiltration repos
Repo Description "niagA oG eW ereH :duluH-iahS" Reversed string used for Shai-Hulud exfiltration repos
Git Branch Name codeql-static-analysis Malicious branch created to bypass audit logs
ICP Canister tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.io C2 network command endpoint for Trivy campaign

Mitigations and Recommendations

Hardening the CI/CD Pipeline

  • Isolate External PRs: Never check out or run code from external forks inside privileged pull_request_target workflows. Build and test PRs strictly in the standard, unprivileged pull_request context.
  • Enforce Privilege Isolation: Split tasks. Use an unprivileged pull_request job to run tests and upload passive data artifacts, then trigger a privileged workflow_run to download the artifacts and comment or publish.
  • Scoped OIDC Bindings: Never bind an OIDC trust wildcard to an entire repository. Explicitly scope bindings to designated workflows on protected branches or tags.
  • Audit Cache Scope: Treat the GitHub Actions build cache as an untrusted attack boundary. Do not generate cache keys from files that external contributors can easily modify.

Securing Local Developer Workstations

  • Disable Run-Scripts: Enforce global package manager configurations to block automatic execution of package lifecycle scripts on install. Run package installations with the ignore flag: npm install --ignore-scripts
  • Freeze the Lockfile: Enforce strict package manager lockfile checks in all automated builds to prevent runtime alterations:
  • For npm: Use npm ci
  • For Yarn: Use yarn install --frozen-lockfile
  • Safe Incident Response: If a workstation is suspected of compromise, isolate and clone/image the physical drive before revoking active developer or GitHub API tokens. Revoking tokens prematurely will immediately trigger the malware's destructive home directory wipe, destroying critical forensic evidence.