Security News

Cybersecurity news aggregator

HIGH Vulnerabilities Snyk

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

The Miasma supply chain attack involved malicious preinstall scripts in at least 32 package releases under the `@redhat-cloud-services` npm namespace, which executed obfuscated payloads to harvest credentials and self-propagate upon installation. Snyk rates the advisory at a CVSS v4.0 score of 9.3 (Critical). Organizations must assume any secrets on affected systems are compromised, should pin away from the malicious versions, reinstall packages with scripts disabled, and immediately rotate all exposed credentials.
Read Full Article →

Snyk Blog In this article TL;DR What happened Technical details The install-time trigger What the payload does Root cause: a compromised account, valid provenance Impact analysis Detection Remediation Timeline Miasma supply chain attack: malicious code found in @redhat-cloud-services npm packages Written by Brian Clark 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 2 curl -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: Triggered on push to any branch. Requested a GitHub OIDC identity token via id-token: write . 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: 1 grep -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: 1 snyk 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: 1 rm -rf node_modules 2 npm install --ignore-scripts You can make that the default for an environment: 1 npm 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 collect

Share this article