Skip to main content

Miasma supply chain attack: malicious code found in @redhat-cloud-services npm packages

Written by

June 1, 2026

0 mins read

On June 1, 2026, researchers identified malicious code embedded in at least 32 package releases published under the @redhat-cloud-services npm namespace, a set of frontend components and API clients that power the Red Hat Hybrid Cloud Console. The compromised releases carry a preinstall script that runs an obfuscated payload the moment a package is installed, harvesting developer and cloud credentials and attempting to spread itself to other packages the victim can publish. The affected packages average roughly 80,000 downloads per week combined, so the blast radius reaches well beyond Red Hat's own pipelines.

The campaign has been named Miasma, and its payload is a lightly reskinned descendant of the (Mini) Shai-Hulud worm that TeamPCP open-sourced earlier this year. If you have installed any @redhat-cloud-services package, or built a project that depends on one, treat this as an active incident and assume any secrets that touched the affected machines are exposed.

TL;DR

  • What: Malicious code (self-propagating worm + credential stealer) embedded in published npm releases.

  • Namespace: @redhat-cloud-services (Red Hat Hybrid Cloud Console frontend components and API clients).

  • Scope: At least 32 package releases across the namespace, ~80,000 combined weekly downloads. Pushed in two waves.

  • CVE: None assigned. Tracked through Snyk advisories. Snyk rates the lead advisory at 9.3 (Critical, CVSS v4.0) with an exploit maturity of Attacked.

  • Root cause: A compromised Red Hat employee GitHub account pushed malicious orphan commits that requested an npm-publishing OIDC token and published packages with valid SLSA provenance.

  • Status: Most malicious versions had been revoked from npm within hours of disclosure; a small number remained live as analysis continued. Investigation is ongoing.

  • Action: Pin away from affected versions, reinstall with scripts disabled, and rotate every credential that was reachable from an affected workstation or CI runner.

What happened

The packages in the @redhat-cloud-services namespace are build-time dependencies for the Hybrid Cloud Console: shared React components (@redhat-cloud-services/frontend-components, frontend-components-utilities, frontend-components-notifications), generated API clients (rbac-client, host-inventory-client, compliance-client, and roughly two dozen more), and supporting tooling. Several of them pull meaningful traffic on their own. As a quick sanity check on the reported scope, the npm downloads API puts the largest packages, like @redhat-cloud-services/types, in the five-figures-per-week range:

1# https://api.npmjs.org/downloads/point/last-week/@redhat-cloud-services%2Ftypes
2curl -s "https://api.npmjs.org/downloads/point/last-week/@redhat-cloud-services%2Ftypes"
3# {"downloads":15060, ... }

Summing the last full week (May 25 to May 31, 2026) across the affected packages yields roughly 79,000 downloads, in line with the ~80,000 figure cited for this incident. The unauthorized modifications were first identified on June 1, 2026.

The malicious releases were published in two waves on June 1. By the time advisories went out, npm had revoked most of the bad versions, with a couple still live during analysis.

Technical details

The install-time trigger

Each compromised release adds an install-time hook. npm runs preinstall scripts automatically during npm install, before any of your own code executes, so simply resolving the dependency is enough to trigger the payload:

1{
2  "scripts": {
3    "preinstall": "node index.js"
4  }
5}

The index.js it invokes is an unusually large, heavily obfuscated JavaScript file. The author relied on eval() and ROT-based string decoding to hide the logic, a tradecraft pattern seen in earlier Shai-Hulud variants. Once decoded, the payload is a multi-stage credential collector and worm.

What the payload does

The functional core matches the (Mini) Shai-Hulud framework though references to Greek mythology have replaced the original Dune-themed cosmetic elements (such as the use of spartan). Newly created attacker repositories carry the description Miasma: The Spreading Blight, which is a useful hunting signal.

On execution, the payload:

  • Harvests secrets and credentials from the local environment and CI context: environment variables, ~/.npmrc tokens, SSH keys, GitHub tokens, and CI/CD secrets.

  • Enumerates cloud identities. The notable change in this variant is a pair of new collectors for GCP and Azure that enumerate every identity the infected host can assume, not just static secrets. Earlier variants focused on lifting credentials; this one is oriented toward mapping and reaching the cloud control plane itself.

  • Self-propagates. It queries the registry for other packages the compromised identity can publish and republishes them, carrying the same payload, which is what turns a single compromised maintainer into a worm.

Root cause: a compromised account, valid provenance

This is the detail worth slowing down on. The malicious code did not slip in through a typosquat or a poisoned transitive dependency. Evidence indicates a Red Hat employee’s GitHub account was compromised and used to push malicious orphan commits directly into two RedHatInsights repositories, bypassing code review.

Those commits added a minimal GitHub Actions workflow that:

  1. Triggered on push to any branch.

  2. Requested a GitHub OIDC identity token via id-token: write.

  3. Executed an obfuscated payload (_index.js) that published the packages to npm.

Because the publish ran inside a legitimate repository's Actions context, the resulting releases shipped with valid SLSA provenance attestations. The provenance was technically correct: the package really was built by that repository's workflow. What it could not tell you is that the workflow itself was unauthorized. This is the same gap TeamPCP exploited against TanStack a few weeks earlier, where forged-but-valid provenance let malicious packages pass naive verification, and it echoes the runner-side token theft seen in the Trivy GitHub Action compromise. Provenance verification is necessary, and it is not sufficient on its own.

Impact analysis

The direct download numbers undercount the real exposure. These are build-time dependencies for an enterprise console, so most installs happen on developer workstations and CI runners, exactly the environments richest in long-lived cloud credentials, registry tokens, and GitHub PATs. The worm behavior compounds this: a single developer who installs an affected version and has publish rights to other packages can seed the next wave.

You are potentially affected if, since the first malicious publication on June 1, 2026, any of the following ran:

  • An npm install / npm ci that resolved an affected @redhat-cloud-services version on a workstation or CI runner.

  • A build in a cloud environment where the runner held GCP, AWS, or Azure identities, given the new cloud-identity collectors.

Exploitation requires no special configuration on your side. The preinstall hook runs by default. The prerequisite is simply having installed an affected version.

Detection

1. Find affected versions in your lockfiles. Search your package-lock.json / pnpm-lock.yaml / yarn.lock for the namespace:

1grep -r "@redhat-cloud-services" package-lock.json pnpm-lock.yaml yarn.lock 2>/dev/null

Cross-reference the resolved versions against the Snyk advisories listed in the References section. Snyk's lead advisory flags @redhat-cloud-services/frontend-components at versions <=7.7.2; cutoffs differ per package, so check each advisory.

2. Scan with Snyk. Snyk's database already carries advisories for the malicious releases, so a standard test flags them:

1snyk test --file=package-lock.json

For organizations, asset discovery and risk-based prioritization help you find every project and runner that pulled an affected version, then rank remediation by how much credential exposure each environment actually carries, rather than chasing every install.

3. Hunt for compromise artifacts. Even after you remove the package, the payload may have run. Look for:

  • New, unexpected repositories in your GitHub org, especially any with the description Miasma: The Spreading Blight.

  • Unrecognized GitHub Actions workflows, particularly minimal ones that request id-token: write and trigger on push to any branch.

  • Newly created personal access tokens, deploy keys, or npm tokens you did not create.

  • Anomalous reads of GCP and Azure identity metadata from build runners.

Remediation

Order matters here. Because this malware family is known to plant persistence and, in some variants, destructive triggers, clean the host before you start revoking the tokens it is watching.

1. Stop installing the bad versions. Pin or override your dependencies to known-good releases, or temporarily remove the affected packages, then verify your lockfile no longer resolves a flagged version.

2. Reinstall with scripts disabled. When you rebuild a potentially affected tree, block install scripts so a lingering malicious version cannot be triggered again:

1rm -rf node_modules
2npm install --ignore-scripts

You can make that the default for an environment:

1npm config set ignore-scripts true

(Re-enable selectively for packages that genuinely need build steps.)

3. Remove persistence. Audit and clean any attacker-planted hooks before touching credentials: editor and agent config, such as .claude/settings.json and .vscode/tasks.json.

4. Rotate everything reachable. Assume exposure of every secret an affected machine could see, and rotate in priority order: npm tokens, GitHub PATs and SSH keys, then cloud credentials. Given the new collectors, pay special attention to cloud identities like GCP, AWS, and Azure, including any roles a CI runner could assume, not only static keys.

5. Clean up GitHub. Delete unauthorized repositories and workflows, review recent Actions runs for the OIDC-publish pattern described above, and confirm no unexpected packages were published under your accounts.

6. Harden the pipeline. Going forward: enforce review on protected branches so orphan commits cannot publish, scope OIDC trust to specific branches and workflows rather than whole repositories, require 2FA with publish protection on npm, and pair provenance verification with behavioral checks instead of trusting attestations alone. Dependency allowlisting, SBOM generation, and an install-age cooldown before adopting fresh releases all reduce the window this kind of attack relies on. Snyk's 10 npm security best practices and 8 tips for securing your CI/CD pipeline cover the rest.

Timeline

  • June 1, 2026: Malicious releases published across the @redhat-cloud-services namespace in a first wave.

  • June 1, 2026 (~1PM UTC): Compromise publicly disclosed; most malicious versions revoked, two still live.

  • June 1, 2026 (~2PM UTC): Root cause published: compromised employee account, OIDC-published packages with valid SLSA provenance.

  • June 1, 2026 (~2:20–3PM UTC): Second wave of malicious commits identified and added to coverage, along with payload detail on the new GCP/Azure identity collectors.

  • Ongoing: Snyk advisories are live for the affected packages. Investigation continues.

Check out the Snyk Vulnerability DB

Trusted data and actionable insights to help you build software securely.