Security
Jun 2, 2026

Miasma npm Worm Steals Cloud Creds and Hijacks CI/CD

When the compromise stops stealing your secrets and starts living in your environment

Give me the TL;DR
Miasma npm Worm Steals Cloud Creds and Hijacks CI/CD
For Qualys admins, NES for .NET directly resolves the EOL/Obsolete Software:   Microsoft .NET Version 6 Detected vulnerability, ensuring your systems remain secure and compliant. Fill out the form to get pricing details and learn more.

The short version: A new campaign called Miasma has compromised more than 30 packages under the @redhat-cloud-services npm namespace. Unlike the supply chain attacks we've tracked over the past year, Miasma doesn't just steal credentials and leave,  it establishes persistence in your developer tooling, injects verified-looking commits into your repos, and turns your pipeline into the next vector. Uninstalling the package does not clean it up.

The blast radius has changed

The attacks are getting harder to contain. Not because the entry points have changed, but because the blast radius has.

Every supply chain attack we've written about over the past year,  the Axios compromise, the TanStack Mini Shai-Hulud campaign, the broader pattern we laid out in our supply chain playbook,  followed a familiar shape. Attacker gets credentials, publishes a malicious package, steals secrets from machines that install it, maybe propagates further through CI/CD. It's a bad day for anyone in the blast radius, but the perimeter is at least conceptually clear: find the compromised machines, rotate credentials, clean up.

Miasma changes that calculus. The new campaign targeting more than 30 packages under the @redhat-cloud-services npm namespace doesn't just steal your secrets and leave. It moves in.

What Miasma actually does

The attack started where these attacks always start; a compromised account. Threat intelligence from Whiteintel suggests a Red Hat employee's GitHub credentials appeared in infostealer logs in April and again in May, weeks before anything went public. The malicious packages themselves were published via GitHub Actions OIDC tokens, meaning the CI/CD pipeline was the actual publishing mechanism. By the time the attack went live on June 1, the attacker had been sitting on access for some time.

More than 30 packages across the @redhat-cloud-services namespace were affected, frontend components, API clients, and developer tooling that together average around 80,000 weekly downloads. Among the confirmed packages:

  • @redhat-cloud-services/vulnerabilities-client
  • @redhat-cloud-services/tsc-transform-imports
  • @redhat-cloud-services/topological-inventory-client
  • @redhat-cloud-services/sources-client
  • @redhat-cloud-services/rule-components
  • @redhat-cloud-services/remediations-client
  • @redhat-cloud-services/rbac-client

Each carries an obfuscated preinstall hook that fires at install time and harvests everything it can find: GitHub Actions secrets, npm tokens, AWS/GCP/Azure credentials, Kubernetes and Vault material, SSH keys, Git credentials, and sensitive local files. The GCP and Azure identity collectors are new to this variant,  previous versions primarily extracted secrets, but Miasma goes further, targeting the cloud identities themselves and the access they represent.

That's the theft component. The part that's new is what it does after.

It turns your pipeline into the attacker

Miasma uses stolen tokens to enumerate repositories the attacker can write to, then injects malicious GitHub Actions workflows directly into those repos. Those commits appear verified and signed, the malware creates them through the createCommitOnBranch GraphQL mutation, making them look like legitimate, trusted changes. Your pipeline doesn't just become a victim. It becomes the next vector.

It escalates, evades, and hides

  • Privilege escalation: It launches a container that bind-mounts the host /etc/sudoers.d.
  • EDR awareness: It checks for endpoint protection,  CrowdStrike, SentinelOne, Carbon Black,  before proceeding.
  • Detection evasion: It generates a unique encrypted payload per infection, making version tracking and detection significantly harder.

It lives in your developer tooling

This is what separates Miasma from its predecessors. It establishes persistence in places that survive a simple npm uninstall:

  • A SessionStart hook injected into Anthropic Claude Code
  • A tasks.json file in VS Code projects set to run on every folder open

We've seen credential theft. We've seen CI/CD propagation. Targeting the developer's local tooling,  the IDE, the AI assistant, the things that run before you've even thought about package security,  is an evolution worth paying attention to.

The attribution context

Miasma is tied to the Mini Shai-Hulud toolkit, the same attack framework behind the TanStack campaign we covered in May. The core tools were open-sourced by a group tracked as TeamPCP (also known as Replicating Marauder, TGR-CRI-1135, and UNC6780).

That open-sourcing is why definitive attribution for Miasma specifically is difficult, once the tools are public, any actor can run them. The observed tradecraft is consistent with TeamPCP's known TTPs, but Wiz researchers note explicitly that copycat actors using the same publicly available tooling cannot be ruled out.

What the open-sourcing also means: this campaign template is now repeatable infrastructure. The next Miasma doesn't require the original group. It just requires someone with credentials and motivation.

One detail worth noting: like previous Mini Shai-Hulud variants, the malware skips execution on Russian-language systems.

This is not a package problem. It's an environment problem.

We keep framing these incidents as "a compromised npm package" because that's the entry point. But Miasma is a useful reminder that the package is just the door. Once the malware is on a machine, it's not thinking in terms of packages anymore. It's thinking in terms of persistent access to the developer's environment, and developer environments increasingly include AI tools, cloud CLIs, and CI systems with elevated permissions that didn't exist five years ago.

The @redhat-cloud-services namespace is heavily used in enterprise Red Hat and OpenShift contexts. The organizations most exposed here aren't scrappy startups running npm install carelessly. They're teams with security programs, compliance requirements, and existing controls,  who now have to answer whether those controls account for install-time hook execution, developer tooling persistence, or verified-looking commits injected by malware.

A wrinkle for teams that rely on provenance checks: the malicious packages were published with valid SLSA attestations, because the publishing identity itself was compromised. When the attacker controls the CI/CD identity, formally signed provenance becomes a mechanism for legitimizing malicious code rather than detecting it. Standard automated security gates likely passed these packages without alerting.

If you're affected

First, and most important: uninstalling the package is not cleanup. The persistence artifacts survive it.

1. Isolate before you remediate. Pull any host that installed an affected version from your environment. Don't attempt cleanup on a live, networked machine.

2. Rotate everything the machine touched. Assume anything the infected host had access to is compromised,  GitHub tokens, npm tokens, AWS/GCP/Azure credentials, Kubernetes secrets, Vault tokens, SSH keys. The malware harvests broadly; rotate broadly.

3. Hunt for persistence artifacts. Audit these locations on any affected machine and CI/CD environment for unauthorized changes:

  • ~/.claude/settings.json
  • .vscode/tasks.json
  • .github/workflows/codeql.yml
  • .github/setup.js

4. Review your GitHub audit log. Look for commits made via the createCommitOnBranch GraphQL mutation. Verified badges are not sufficient,  this is exactly how the malware creates its injected workflows. Also check for unexpected repositories created, new access tokens minted, or suspicious workflow executions.

5. Invalidate build artifacts from the exposure window. Any container image, npm package, or deployment artifact produced while the malicious package was installed should be treated as potentially compromised. Suspend affected workflow runs and rebuild from a clean state.

6. Harden going forward.

  • Use npm ci instead of npm install in CI/CD.
  • Commit and enforce lockfiles.
  • Scope token permissions as narrowly as possible,  the broader the token, the wider the worm propagates.
  • Consider adding install-script restrictions via --ignore-scripts in CI contexts where preinstall hooks have no legitimate business running.

The pattern behind the pattern

We've now written about enough of these to say with confidence that the technical recommendations don't change much between incidents. Lockfiles. Pinned versions. Least-privilege tokens. The hygiene advice is well-established.

What's less well-established is the organizational acknowledgment that the threat model has shifted. These aren't attacks on your application's runtime. They're attacks on your development environment, your pipelines, and increasingly the tools your developers use every day.

The question for engineering leaders isn't just "are we scanning our dependencies" — it's "if an attacker had thirty minutes of install-time execution on a developer machine, what would they find, and what could they reach?"

At HeroDevs, we work with organizations on the less glamorous side of this problem: the dependencies that aren't actively maintained, the packages that have fallen into end-of-life status and are still quietly running in production, the corners of the dependency graph that don't get audited because nobody's sure who owns them.

Supply chain attacks don't just target popular packages. They target neglected ones. If you're carrying EOL dependencies and haven't mapped what they have access to, that's worth doing before the next campaign gives you a reason to.

Table of Contents
Author
Allison Vorthmann
Engineering Manager
Open Source Insights Delivered Monthly