The Miasma Attack
How 31 Red Hat npm Packages Were Weaponized Against Developers
On June 1, 2026, one of the most sophisticated npm supply chain attacks in recent memory hit developers and enterprises relying on Red Hat's official frontend tooling. Dubbed Miasma, the campaign quietly embedded a self-propagating credential-stealing worm into 31 packages under the @redhat-cloud-services npm namespace packages that collectively see around 80,000 downloads every week.
This is not a story about a sketchy package with a typo-squatted name. The attackers hijacked a trusted, legitimate Red Hat namespace and published backdoored versions of widely-used frontend components and API clients. By the time researchers noticed, thousands of developers, CI pipelines, and cloud environments may have unknowingly run the malware.
Congratulations, everyone. We've done it again.
Here's everything you need to know.
Background: What Is @redhat-cloud-services?
The @redhat-cloud-services npm scope is Red Hat's official namespace for frontend components and API client libraries that power the Red Hat Hybrid Cloud Console the web interface used by enterprises to manage OpenShift, RHEL, Insights, and other Red Hat cloud products.
Packages in this scope include:
- Frontend UI components (navigation, notifications, forms, remediations)
- API client libraries for services like RBAC, compliance, entitlements, patch, and host inventory
- Developer tooling like ESLint configs, TypeScript transform utilities, and test utilities
These are not obscure, corner-of-the-internet libraries maintained by one person and their cat. Many enterprises and Red Hat partners pull these packages into their own build pipelines, CI runners, and developer workstations. That's exactly what made them such a high-value target and why the attacker picked them instead of, say, left-pad 2: electric boogaloo.
How the Attack Happened: The Initial Compromise
Red Hat's own security advisory confirmed the root cause: a compromised GitHub account was used to inject malicious code into packages maintained in the RedHatInsights GitHub organization.
Specifically, researchers at Snyk determined that the attacker compromised a Red Hat employee's GitHub account and used it to push malicious orphan commits to repositories in the RedHatInsights GitHub organization. Those commits were crafted to request an npm-publishing OIDC (OpenID Connect) token through GitHub Actions and they succeeded.
This is a particularly insidious vector. Because the commits came from a legitimate, previously-trusted GitHub account, and because they triggered the normal GitHub Actions CI/CD workflow, the resulting npm packages were published with valid SLSA (Supply chain Levels for Software Artifacts) provenance. In other words, the packages appeared completely authentic signed, sealed, and delivered with all the right paperwork. The software supply chain equivalent of a perfect forgery that sails through every customs check.
Signature verification and provenance checking would not have flagged them. "But it has a badge!" Yes. So did the Trojan Horse, metaphorically speaking.
The malicious releases were pushed in two waves across the RedHatInsights/javascript-clients, RedHatInsights/frontend-components, and RedHatInsights/platform-frontend-ai-toolkit repositories. StepSecurity, who discovered and disclosed the attack, filed issues directly in all three repos to coordinate takedown, which, given the circumstances, must have been a fun GitHub notification for the maintainers to wake up to.
The Malware: A Three-Stage Credential Worm
Stage 1 The Preinstall Hook
Every compromised package had one thing added to its package.json: a preinstall lifecycle hook.
"scripts": {
"build": "tsc",
"preinstall": "node index.js"
}
The preinstall hook fires before any application code runs and before any other dependencies are installed the very instant npm install processes the package. There is no prompt, no warning, no pop-up asking "are you sure you want this random 4.2 MB file to execute with your full user privileges?" npm just... does it. Silently. Helpfully.
Speaking of that index.js file: it is 4.2 MB. For context, a frontend library's entire source of truth should not be larger than most Hollywood screenplays. If you ever see a suspiciously chunky index.js in a dependency, that's the software equivalent of a violin case that makes faint ticking sounds. But to be fair, most developers never look inside their node_modules folder, a directory that by this point contains more secrets than the CIA.
Stage 2 Three Layers of Obfuscation (Villains Love An Onion)
Researchers at StepSecurity performed static analysis on @redhat-cloud-services/host-inventory-client@5.0.3 and found the payload hidden behind three obfuscation layers. The attackers, apparently feeling theatrical, stacked them like a malicious parfait.
Outer layer ROT-21 encoding. The entire payload is wrapped in a try { eval(...) } catch(e) {} block. The inner content uses a ROT-21 Caesar cipher (shift 21 applied to all alphabetic characters), with character codes stored as a large numeric array reconstructed at runtime via String.fromCharCode. The silent catch block ensures no errors appear in the developer console regardless of what goes wrong. It fails quietly. Like a true professional or a very experienced intern.
ROT-21, by the way, is essentially ROT-13's less popular cousin. It's not exactly unbreakable cryptography. The primary purpose here isn't security; it's to slow down the casual grep that might otherwise notice something suspicious.
Middle layer JavaScript obfuscation. The decoded payload passes through a standard JavaScript obfuscator, shuffling variable names and control flow to defeat static analysis tools. At this point the payload looks like the output of a keyboard smashed by a distressed cat, but it works perfectly.
Inner layer a dynamic loader. The inner core is a multi-stage loader that ultimately executes a Bun runtime process as the final stage of credential harvesting. Why Bun? Because many network monitoring and EDR tools are not tuned to flag suspicious outbound connections from Bun processes the way they flag Node.js. Basically, the malware dressed up as the new kid at school and walked straight past the hall monitors.
Stage 3 The Credential Harvester (AKA The "You Left Your Keys On The Table" Stage)
Once fully loaded, the payload conducts a comprehensive sweep of every credential it can reach on the machine or CI runner. And when we say comprehensive, we mean it went through your digital pockets like an extremely motivated pickpocket at a developer conference. The targets include:
- AWS environment variables, STS response XML parsing, IMDSv2 metadata endpoint headers, and credential file paths
- Azure ARM environment variables and regex patterns for Key Vault key prefixes
- GCP service account environment variables and PEM key regexes
- HashiCorp Vault token environment variables, request headers, and filesystem paths like
~/.vault-token - Kubernetes service account tokens at
/var/run/secrets/kubernetes.io/serviceaccount/token - GitHub Actions OIDC tokens via the
ACTIONS_ID_TOKEN_REQUEST_TOKENand related environment variables - npm tokens from
.npmrcfiles and environment variables - CircleCI tokens from CI environment variables
- Password managers Bitwarden and 1Password via their CLI environment variables and local socket paths
- SSH keys from
~/.ssh/ - Generic credential sweep a broad regex that catches anything resembling a secret token
If your secrets were on that machine, they're probably in someone else's git repo now. The payload also reads from /proc/mem on Linux a technique to extract secrets from process memory, including credentials that were set and then unset before the malicious code started. "But I unset the environment variable!" Did you, though? Did you really?
The Exfiltration Channel (Or: How To Steal Data Without Looking Like You're Stealing Data)
Here is where Miasma earns genuine, grudging, deeply uncomfortable respect. According to the Mend.io payload analysis, no attacker-controlled domain appears anywhere in the payload. Every URL it contacts is a legitimate vendor endpoint: GitHub's API, the npm registry, AWS metadata, HashiCorp Vault, Microsoft Graph, Google APIs, Sigstore.
Exfiltration is performed through the GitHub API itself. The payload uses the victim's own stolen GitHub token to commit stolen credentials to a repository through GitHub's perfectly normal, perfectly legitimate, completely unremarkable commit API. Your network traffic logs just see GitHub API calls. Nothing to flag. Nothing to block. Please enjoy the rest of your Monday.
One report also noted that some traffic was disguised to look like calls to api.anthropic.com/v1/api a domain that would go completely unnoticed in organizations using Claude. (Hi. We're as surprised as you are.)
The Worm Component: Now It's Everyone's Problem
What elevates Miasma above a simple credential stealer is its self-propagating behavior. Once it has harvested npm tokens from the victim's environment, the malware attempts to use those tokens to republish other packages the victim has access to injecting the same malicious payload into them.
It's a supply chain worm: it spreads through the trust relationships between developers and their packages. You were a victim. Now, briefly and without your knowledge, you were also a vector. The software equivalent of sneezing on someone who then sneezes on a conference room of 80,000 weekly downloaders.
Snyk's analysis classified Miasma as a variant of the (Mini) Shai-Hulud worm a malware family previously linked to the threat actor group TeamPCP, who helpfully open-sourced the attack tools earlier in 2026. Nothing says "we've won and we don't care who knows it" like publishing your malware toolkit to the open web. Attribution is now essentially impossible, since any sufficiently motivated person with a GitHub account can run this class of attack.
Affected Packages and Versions
The following 31 packages and specific versions were confirmed as carrying the malicious payload. Scan this list carefully. If any of these touched your environment on or after June 1, 2026, it's incident response time and your weekend plans are cancelled.
| Package | Compromised Version |
|---|---|
@redhat-cloud-services/chrome | 2.3.1 |
@redhat-cloud-services/compliance-client | 4.0.3 |
@redhat-cloud-services/config-manager-client | 5.0.4 |
@redhat-cloud-services/entitlements-client | 4.0.11 |
@redhat-cloud-services/eslint-config-redhat-cloud-services | 3.2.1 |
@redhat-cloud-services/frontend-components | 7.7.2 |
@redhat-cloud-services/frontend-components-advisor-components | 3.8.2 |
@redhat-cloud-services/frontend-components-config | 6.11.3 |
@redhat-cloud-services/frontend-components-config-utilities | 4.11.2 |
@redhat-cloud-services/frontend-components-notifications | 6.9.2 |
@redhat-cloud-services/frontend-components-remediations | 4.9.2 |
@redhat-cloud-services/frontend-components-testing | 1.2.1 |
@redhat-cloud-services/frontend-components-translations | 4.4.1 |
@redhat-cloud-services/frontend-components-utilities | 7.4.1 |
@redhat-cloud-services/hcc-feo-mcp | 0.3.1 |
@redhat-cloud-services/hcc-kessel-mcp | 0.3.1 |
@redhat-cloud-services/hcc-pf-mcp | 0.6.1 |
@redhat-cloud-services/host-inventory-client | 5.0.3 |
@redhat-cloud-services/insights-client | 4.0.4 |
@redhat-cloud-services/integrations-client | 6.0.4 |
@redhat-cloud-services/javascript-clients-shared | 2.0.8 |
@redhat-cloud-services/notifications-client | 6.1.4 |
@redhat-cloud-services/patch-client | 4.0.4 |
@redhat-cloud-services/quickstarts-client | 4.0.11 |
@redhat-cloud-services/rbac-client | 9.0.3 |
@redhat-cloud-services/remediations-client | 4.0.4 |
@redhat-cloud-services/rule-components | 4.7.2 |
@redhat-cloud-services/sources-client | 3.0.10 |
@redhat-cloud-services/topological-inventory-client | 3.0.10 |
@redhat-cloud-services/tsc-transform-imports | 1.2.2 |
@redhat-cloud-services/types | 3.6.1 |
Red Hat's Response
Red Hat published a security advisory (RHSB-2026-006) on June 1, 2026. Their statement confirmed the supply chain compromise and noted that Red Hat engineering removed the compromised versions from npm following disclosure. Red Hat Product Security also stated it was conducting build system and dependency tracking analysis to confirm whether any product builds incorporated the compromised package versions.
As of the advisory, Red Hat indicated that based on current findings, no customer action was required from a product perspective but that investigation was ongoing. Which is security advisory language for "we're still figuring out how deep this goes, please hold."
To their credit, the compromised package versions were revoked from npm within hours of the initial disclosure. That's a fast response. The malware had already done its job in those hours, but still fast response.
What You Should Do If You're Affected
If any of the listed package versions were installed in your environment after June 1, 2026, treat the incident as an active compromise. Put the coffee down. Cancel your lunch. This is happening now.
Immediately rotate all credentials accessible from the affected machine or CI runner: GitHub personal access tokens and OIDC tokens, npm tokens, AWS access keys, Azure service principal credentials, GCP service account keys, Kubernetes service account tokens, HashiCorp Vault tokens, CircleCI tokens, SSH keys, and anything stored in Bitwarden or 1Password CLI sessions. Yes, all of them. Yes, that's a lot. Yes, this is why we don't reuse credentials. Lesson learned.
Important and this one is genuinely not funny: Security researchers noted a "dead-man switch" behavior in the Miasma payload. You should isolate affected machines before revoking tokens, not after. Revoking tokens while the malware is still active on the system may trigger additional exfiltration or destructive actions. First isolate, then rotate. Don't go poking the angry thing while it still has teeth.
Reinstall packages safely by pinning to safe versions and disabling scripts during install:
npm install --ignore-scripts
Consider putting this in a frame on your wall.
Audit your CI logs for any npm install steps that ran on or after June 1, 2026, and check for unexpected outbound connections to GitHub's API, especially commit creation mutations, from your runners.
Check whether your packages were re-published. If you maintain npm packages and any npm tokens were accessible from an affected environment, check your package publish history for unauthorized releases. The worm may have used you as a launchpad.
Scan your git history in repos accessible from affected runners for unauthorized commits, particularly commits to branches named chore/add-cod or similar, which were identified as the malware's exfiltration branch naming convention. chore/add-cod love that they dressed it up as a mundane housekeeping task. Very on-brand for malware in 2026.
The Bigger Picture: Why This Attack Matters
Miasma is a textbook demonstration of why supply chain security has become the most urgent problem in software development. Here are a few things that make this attack particularly instructive:
Trusted namespace, valid provenance. This was not a typosquatting attack. The attacker used a legitimate Red Hat employee's GitHub account to publish through the real Red Hat CI/CD pipeline, producing packages with valid SLSA provenance attestations. The usual defenses checking the publisher, verifying the source repository, inspecting provenance would not have caught this. All the security theater passed. The attacker walked through the metal detector and it beeped "approved."
The preinstall hook problem. npm's lifecycle hooks remain one of the most dangerous surfaces in the ecosystem. A preinstall script runs with full user privileges before any human has a chance to review it, and the vast majority of developers never inspect the scripts section of transitive dependencies before running npm install. To be fair, in a typical project with 800 dependencies, you'd be retired before you finished reading them all. This is a problem with no good solution, which is why attackers keep exploiting it.
Exfiltration via legitimate APIs. By routing stolen data through the GitHub API using the victim's own token, the attackers ensured their traffic was indistinguishable from normal developer activity. No suspicious domain, no self-signed certificate, no "definitely-not-a-hacker.ru" IP address. Just GitHub calls. Your SIEM saw nothing. Your network team saw nothing. Everyone had a lovely Tuesday.
The worm factor. The self-propagation capability means that even a single infected developer machine could, if not caught quickly, spread the malicious payload to packages maintained by that developer extending the blast radius far beyond Red Hat's own ecosystem. One compromised npm install can, in theory, become thousands. Watching a supply chain worm propagate in real time must feel a bit like watching dominoes fall, except the dominoes are production credentials and cloud environments.
Attribution is getting harder. TeamPCP open-sourcing the Shai-Hulud tooling means that any sufficiently motivated actor can now run this class of attack. The security community should expect more Miasma-style campaigns across other ecosystems. We are, unfortunately, in an era where the barrier to running a sophisticated supply chain attack is a GitHub account and an afternoon.
Key Takeaways for Defenders
The Miasma attack reinforces several practices that security teams should be evaluating right now. Some of these you've heard before. You probably nodded along in the last post-mortem and then didn't change anything. Now might be the time.
Pin dependencies to exact versions in production and CI. Floating version ranges (^7.7.0) are convenient right up until they automatically pull in a compromised release. Convenience is the enemy of security and also of a quiet weekend.
Treat CI runners as untrusted machines. Secrets available in CI should be scoped minimally and rotated frequently. Assume that any CI run that installs external packages is a potential exfiltration vector because, as we've now confirmed twice in two years, it is.
Monitor for anomalous preinstall scripts. Tools like StepSecurity's Harden-Runner, Snyk, Socket, and JFrog Artifactory can flag packages that suddenly declare lifecycle hooks they didn't have in previous versions. Use them. The "I'll set that up next sprint" sprint has been running for three years.
Use npm install --ignore-scripts for packages where lifecycle scripts are not required, particularly in CI. This is one of those flags that has existed in npm for years and would have blocked this entire attack. The instructions were on the box.
Audit npm token scopes. npm publish tokens should be scoped to specific packages and should have the shortest viable expiry. A harvested token that can only publish to one package is far less useful to an attacker than one that can publish to your entire organization. Least privilege is not just a conference talk topic.
Require MFA and phishing-resistant authentication for all accounts with access to production GitHub repositories and npm organizations. The initial compromise here was a GitHub account one of the most common and consequential vectors in supply chain attacks. If a key account in your organization is still protected by only a password, please fix that before you finish reading this sentence.
Timeline
| Time | Event |
|---|---|
| June 1, 2026 | Malicious packages published to npm in two waves via compromised GitHub Actions OIDC tokens |
| June 1, 2026 | StepSecurity's AI Package Analyst flags payload size anomaly within minutes turns out 4.2 MB is suspicious for a library |
| June 1, 2026 | StepSecurity files disclosure issues in all three affected RedHatInsights repositories |
| June 1, 2026 | Red Hat engineering removes compromised versions from npm |
| June 1, 2026 | Snyk, Mend.io, Socket, and others publish independent technical analyses |
| June 1, 2026 | Red Hat publishes RHSB-2026-006 security advisory |
| June 2, 2026 | Investigation ongoing; payload deobfuscation continuing; developers staring at their node_modules folders with new, existential dread |
References
- Aikido Security — https://www.aikido.dev/blog/red-hat-npm-packages-compromised-credential-stealing-worm
- The Hacker News — https://thehackernews.com/2026/06/miasma-supply-chain-attack-compromises.html
- BleepingComputer — https://www.bleepingcomputer.com/news/security/red-hat-npm-packages-compromised-to-steal-developer-credentials/
- LF32 Research — https://lf32.vercel.app/blog/2026-06-02
This post will be updated as further technical analysis emerges. If you have indicators of compromise or additional forensic findings to share, reach out to the security research community through the disclosure issues linked in the RedHatInsights repositories. And maybe just this once read the scripts section before you npm install.
Share this article
Found this helpful? Share it with others.
