Microsoft Threat Intelligence disclosed on June 2, 2026, that attackers compromised the RedHatInsights/javascript-clients CI/CD pipeline and published 32 malicious @redhat-cloud-services npm packages across more than 90 versions through a legitimate GitHub Actions OIDC trusted-publishing workflow. The uncomfortable part is not just that npm packages were poisoned. It is that the packages appeared to come through the very machinery the ecosystem has been told to trust. “Miasma: The Spreading Blight” is a melodramatic campaign marker, but the attack itself is brutally practical: steal credentials, reuse publishing rights, and turn provenance into camouflage.
Supply-chain security has spent years teaching developers to prefer signed artifacts, automated release pipelines, provenance metadata, and trusted publishing over manual token handling. That advice remains sound. But the Red Hat npm Miasma campaign shows the obvious corollary: once attackers compromise the release path itself, every downstream trust signal becomes part of the disguise.
According to Microsoft’s analysis, the compromised packages were not crude lookalikes uploaded from a throwaway account. They were published under the legitimate
This is why the incident matters beyond the affected package list. The campaign did not merely exploit sloppy consumers who install random dependencies. It attacked the relationship between CI/CD identity, registry trust, and automated software consumption.
The attacker’s advantage was timing and placement. A malicious package arriving through a preexisting trusted namespace can move farther and faster than malware that has to persuade victims one by one. In modern JavaScript development, transitive dependency is not a footnote; it is the normal way code enters a build.
In this case, the hook executed a malicious
The campaign’s elegance is ugly. It does not need an end user to double-click an attachment, accept a macro, or run a pasted command from a forum. It waits for a build, package install, or developer workstation dependency update, then rides the normal behavior of the package manager.
For WindowsForum readers, the Windows angle is not that this is a Windows-first campaign. Microsoft says Linux CI/CD runners appeared to be the primary target. The Windows angle is that modern development estates are mixed by default: Windows laptops, WSL, Linux runners, macOS maintainers, cloud-hosted build workers, and containers stitched together by tokens that often outlive any one machine.
That matters because security monitoring often forms habits around expected process trees. If the obvious suspicious chain is
This is the same pattern defenders have seen repeatedly with PowerShell, Python, WMI,
The cross-platform element also undercuts a comforting but outdated assumption. Developer security cannot be separated cleanly by operating system anymore. A Windows developer may trigger a Linux runner. A Linux runner may leak a GitHub token that rewrites a repository consumed by Windows builds. A macOS maintainer may publish a package that lands on a Windows endpoint during an Electron build.
Still, obfuscation is not the strategic novelty here. Malware authors have buried strings and staged payloads for decades. What makes this campaign notable is that the obfuscation sat inside packages that already had a trust story attached to them.
That combination creates a difficult defender decision. If every obfuscated install script becomes an emergency, teams drown in noise. If trusted provenance lowers scrutiny too much, an attacker who compromises the publisher path gets a free pass. The hard problem is not recognizing that a 4.29 MB obfuscated
The leftover source-map metadata is a useful reminder. Attackers often optimize for operational success rather than perfect forensic cleanliness. Build artifacts, metadata mismatches, unusual file sizes, strange process trees, and unexpected runtime downloads are the seams where defenders still get leverage.
In CI/CD, secrets are concentrated by design. A runner may have short-lived tokens, cloud metadata access, package-publishing rights, repository write permissions, and deployment credentials available within the same job context. Those credentials are supposed to be scoped and ephemeral, but the job’s process memory can still become a target while the run is active.
Microsoft says the malware scanned Linux
This is where the campaign becomes more than another npm compromise. It shows attackers thinking like platform engineers. They are not simply stealing whatever
That is not a failure of provenance as a concept. It is a reminder of its boundary. Provenance can tell you a great deal about how an artifact was produced, but it cannot by itself prove that the producing workflow was uncompromised, that the maintainer identity was safe, or that the build process did not emit hostile code.
This distinction will annoy people who want supply-chain security to have a single decisive green check. There is no such check. Trusted publishing reduces some risks, especially stolen long-lived npm tokens, but it concentrates importance around repository controls, workflow permissions, branch protection, runner isolation, and review of generated artifacts.
The uncomfortable lesson is that modern software trust is cumulative. A signature helps. A protected branch helps. A least-privilege workflow helps. Reproducible builds help. Runtime monitoring helps. None of them alone can carry the weight vendors sometimes imply when they talk about “secure by default” pipelines.
Classic worms exploited network reachability. This one exploited authority reachability. If a maintainer account could publish packages, if a CI job could request a token, if a repository could be modified through an API, the malware treated those rights as pathways.
The use of victim-owned GitHub assets for exfiltration and staging is equally revealing. Instead of depending only on a single command-and-control endpoint that defenders can block, the campaign reportedly created public repositories under victim accounts and committed stolen credential data into them. That turns normal developer infrastructure into both a storage layer and a camouflage layer.
This is a nasty inversion of platform trust. GitHub traffic is common in developer networks. Registry traffic is common in build networks. Runtime downloads are common in modern toolchains. The attacker wins by making each individual action look plausible enough that only the sequence tells the truth.
That changes how responders should think about containment. The standard reflex after credential exposure is to revoke and rotate immediately. That is still necessary, but campaigns that include destructive tripwires force teams to plan the order of operations more carefully: isolate hosts, preserve evidence, disable execution paths, then rotate credentials at speed.
It also highlights a growing trend in developer-focused intrusions. Attackers are not content to steal a token and leave. They increasingly build deterrence and persistence into the intrusion: monitors, decoys, delayed payloads, secondary channels, and destructive branches intended to punish investigation or cleanup.
The correct response is not paralysis. It is preparation. Incident playbooks for CI/CD compromise need to assume that revocation, repository cleanup, runner rebuilds, package unpublishing, and cloud key rotation may all have to happen as one coordinated operation.
That includes internal enterprise package feeds. In fact, private registries may be worse in some environments because they receive less external scrutiny. A company may trust its internal packages implicitly, run install scripts freely, and allow broad CI access because the package name begins with the organization’s own scope.
The Red Hat association also underscores why namespace trust is not enough. Developers often treat known scopes as safer than random packages, and usually they are. But “safer” is not “safe,” especially when a compromised upstream pipeline can publish through a legitimate channel.
The most important question for enterprises is not whether they used one of the listed packages. That is the first question, and it must be answered. The second question is whether their own publishing pipelines would fail in the same way if an attacker reached a maintainer workflow.
Most Windows software teams now depend on JavaScript somewhere: web front ends, admin portals, Electron apps, documentation tooling, test harnesses, build scripts, Teams apps, Azure deployment helpers, or internal dashboards. A compromised npm package can enter the Windows estate through build tooling long before it appears as an endpoint alert on a user’s desktop.
The Windows endpoint also remains a credential cache. Developer machines may hold SSH keys, Git credentials, browser sessions, cloud CLI profiles,
For defenders using Microsoft Defender XDR or similar tooling, the practical signal is behavioral. Look for unusual lifecycle script execution, Bun downloads from unexpected processes,
That does not make the recommendation useless. It means organizations should distinguish between developer convenience and build-system policy. A hardened CI path for dependency resolution can use
Dependency pinning is similarly unglamorous but important. Automatic upgrades are convenient until the update stream becomes the infection stream. Pinning known-good versions, validating lockfiles, and delaying automatic adoption of new package versions can turn a fast-moving supply-chain incident from an immediate compromise into an alertable discrepancy.
The deeper mitigation is to reduce the authority available to any one job. A build that installs dependencies should not automatically have the right to publish packages, rewrite repositories, read organization secrets, and reach cloud metadata services unless the workflow genuinely requires it. Least privilege is tedious until the alternative is a worm with a registry account.
That distinction no longer survives contact with modern supply-chain attacks. A build runner can publish production code. A package workflow can mint trusted artifacts. A repository token can change what thousands of downstream systems consume. In practical terms, CI/CD is production infrastructure with a better disguise.
That means build environments need the same seriousness applied to servers handling customer data. Runners should be ephemeral where possible. Secrets should be scoped, short-lived, and bound to specific workflows. Branch protections should matter. Default token permissions should be reduced. Publishing jobs should be separated from test jobs. Outbound network access should be observable and, where feasible, constrained.
Most of all, provenance should be treated as evidence, not absolution. A signed malicious package is still malicious. An attested compromised build is still compromised. The point of these systems is to narrow uncertainty, not eliminate the need for judgment.
The Trusted Path Became the Attack Surface
Supply-chain security has spent years teaching developers to prefer signed artifacts, automated release pipelines, provenance metadata, and trusted publishing over manual token handling. That advice remains sound. But the Red Hat npm Miasma campaign shows the obvious corollary: once attackers compromise the release path itself, every downstream trust signal becomes part of the disguise.According to Microsoft’s analysis, the compromised packages were not crude lookalikes uploaded from a throwaway account. They were published under the legitimate
@redhat-cloud-services scope, through a legitimate GitHub Actions OpenID Connect flow, with authentic provenance signatures. For developers and automated dependency systems, that is precisely the sort of release that should look clean.This is why the incident matters beyond the affected package list. The campaign did not merely exploit sloppy consumers who install random dependencies. It attacked the relationship between CI/CD identity, registry trust, and automated software consumption.
The attacker’s advantage was timing and placement. A malicious package arriving through a preexisting trusted namespace can move farther and faster than malware that has to persuade victims one by one. In modern JavaScript development, transitive dependency is not a footnote; it is the normal way code enters a build.
Preinstall Was the Small Door With the Big Blast Radius
The initial execution point was an npmpreinstall hook. That sounds almost mundane, which is precisely why it is dangerous. Lifecycle scripts are old plumbing in the JavaScript ecosystem, and they can run automatically when packages are installed directly or pulled in as dependencies.In this case, the hook executed a malicious
index.js dropper without requiring user interaction. Microsoft describes that script as a heavily obfuscated 4.29 MB payload, replacing the legitimate file while leaving source-map metadata unchanged. That mismatch points toward release-pipeline tampering rather than a simple source-code change reviewed in the open.The campaign’s elegance is ugly. It does not need an end user to double-click an attachment, accept a macro, or run a pasted command from a forum. It waits for a build, package install, or developer workstation dependency update, then rides the normal behavior of the package manager.
For WindowsForum readers, the Windows angle is not that this is a Windows-first campaign. Microsoft says Linux CI/CD runners appeared to be the primary target. The Windows angle is that modern development estates are mixed by default: Windows laptops, WSL, Linux runners, macOS maintainers, cloud-hosted build workers, and containers stitched together by tokens that often outlive any one machine.
Bun Was Not the Vulnerability, It Was the Escape Hatch
One of the more interesting technical choices in the campaign was the use of Bun. The malware decrypted embedded blobs, downloaded the correct Bun runtime for the victim platform, and launched its next stage through Bun rather than staying entirely inside Node.js.That matters because security monitoring often forms habits around expected process trees. If the obvious suspicious chain is
npm to node to shell activity, moving execution into bun creates a less familiar branch. Bun is a legitimate JavaScript runtime, and its presence alone is not malicious. But in this campaign, the runtime became an evasion layer: node spawned shell logic, the shell obtained Bun, and Bun executed the payload.This is the same pattern defenders have seen repeatedly with PowerShell, Python, WMI,
curl, mshta, and other dual-use tools. Attackers do not need obscure binaries when legitimate developer tooling is already allowed through the door. The best living-off-the-land technique is the one that looks like the environment’s own workflow.The cross-platform element also undercuts a comforting but outdated assumption. Developer security cannot be separated cleanly by operating system anymore. A Windows developer may trigger a Linux runner. A Linux runner may leak a GitHub token that rewrites a repository consumed by Windows builds. A macOS maintainer may publish a package that lands on a Windows endpoint during an Electron build.
Obfuscation Bought Time, Not Magic
The Miasma payload used several layers of concealment: ROT-style transformations, AES-128-GCM encrypted blobs, string-array obfuscation, and a custom cryptographic string routine using PBKDF2-HMAC-SHA-256 with 200,000 iterations. That is more than casual hiding. It is designed to slow static analysis, signature creation, and confident triage.Still, obfuscation is not the strategic novelty here. Malware authors have buried strings and staged payloads for decades. What makes this campaign notable is that the obfuscation sat inside packages that already had a trust story attached to them.
That combination creates a difficult defender decision. If every obfuscated install script becomes an emergency, teams drown in noise. If trusted provenance lowers scrutiny too much, an attacker who compromises the publisher path gets a free pass. The hard problem is not recognizing that a 4.29 MB obfuscated
index.js is suspicious; it is noticing it quickly when it appears inside an otherwise legitimate release stream.The leftover source-map metadata is a useful reminder. Attackers often optimize for operational success rather than perfect forensic cleanliness. Build artifacts, metadata mismatches, unusual file sizes, strange process trees, and unexpected runtime downloads are the seams where defenders still get leverage.
The Credential Harvester Treated CI as the Prize
The campaign’s credential theft was broad: GitHub, npm, AWS, Azure, Google Cloud Platform, HashiCorp Vault, Kubernetes, CircleCI, local SSH keys, CLI credentials, browser data, and wallet files all appear in Microsoft’s description. That breadth is not accidental. A compromised developer machine is useful, but a compromised CI environment can be a distribution platform.In CI/CD, secrets are concentrated by design. A runner may have short-lived tokens, cloud metadata access, package-publishing rights, repository write permissions, and deployment credentials available within the same job context. Those credentials are supposed to be scoped and ephemeral, but the job’s process memory can still become a target while the run is active.
Microsoft says the malware scanned Linux
/proc entries to locate the GitHub Actions Runner.Worker process and scrape secret-like values from memory. That is a direct attack on the gap between secret masking in logs and secret presence in runtime memory. Masking prevents accidental disclosure in output; it does not make secrets disappear from the process that needs to use them.This is where the campaign becomes more than another npm compromise. It shows attackers thinking like platform engineers. They are not simply stealing whatever
.npmrc file happens to exist. They are mapping where identity lives during automated publishing and looking for the moment when the system itself has enough authority to act.Provenance Became a Mask, Not a Guarantee
SLSA provenance, Sigstore-style attestations, and OIDC-based publishing are meant to answer a real problem: “Did this package come from the workflow and source it claims to come from?” In the Miasma campaign, the answer could be “yes” while the result was still malicious.That is not a failure of provenance as a concept. It is a reminder of its boundary. Provenance can tell you a great deal about how an artifact was produced, but it cannot by itself prove that the producing workflow was uncompromised, that the maintainer identity was safe, or that the build process did not emit hostile code.
This distinction will annoy people who want supply-chain security to have a single decisive green check. There is no such check. Trusted publishing reduces some risks, especially stolen long-lived npm tokens, but it concentrates importance around repository controls, workflow permissions, branch protection, runner isolation, and review of generated artifacts.
The uncomfortable lesson is that modern software trust is cumulative. A signature helps. A protected branch helps. A least-privilege workflow helps. Reproducible builds help. Runtime monitoring helps. None of them alone can carry the weight vendors sometimes imply when they talk about “secure by default” pipelines.
The Worm Logic Was Built Into the Business Model of Packages
Microsoft’s write-up describes self-propagation behavior: the malware searched for maintainer-owned packages, exchanged OIDC tokens for publishing rights, republished poisoned packages, and injected code into repositories where it could. That is worm logic adapted to the package ecosystem.Classic worms exploited network reachability. This one exploited authority reachability. If a maintainer account could publish packages, if a CI job could request a token, if a repository could be modified through an API, the malware treated those rights as pathways.
The use of victim-owned GitHub assets for exfiltration and staging is equally revealing. Instead of depending only on a single command-and-control endpoint that defenders can block, the campaign reportedly created public repositories under victim accounts and committed stolen credential data into them. That turns normal developer infrastructure into both a storage layer and a camouflage layer.
This is a nasty inversion of platform trust. GitHub traffic is common in developer networks. Registry traffic is common in build networks. Runtime downloads are common in modern toolchains. The attacker wins by making each individual action look plausible enough that only the sequence tells the truth.
The Destructive Tripwire Changes the Incident-Response Math
The planted honeytoken with a threat-like label warning that invalidation could “nuke” the owner’s computer is one of the campaign’s more theatrical elements. But the destructive behavior Microsoft describes is not just theater. If triggered, the malware could attempt to wipe the victim’s home directory and Documents folder.That changes how responders should think about containment. The standard reflex after credential exposure is to revoke and rotate immediately. That is still necessary, but campaigns that include destructive tripwires force teams to plan the order of operations more carefully: isolate hosts, preserve evidence, disable execution paths, then rotate credentials at speed.
It also highlights a growing trend in developer-focused intrusions. Attackers are not content to steal a token and leave. They increasingly build deterrence and persistence into the intrusion: monitors, decoys, delayed payloads, secondary channels, and destructive branches intended to punish investigation or cleanup.
The correct response is not paralysis. It is preparation. Incident playbooks for CI/CD compromise need to assume that revocation, repository cleanup, runner rebuilds, package unpublishing, and cloud key rotation may all have to happen as one coordinated operation.
The Red Hat Name Raised the Stakes, but the Pattern Is Bigger
The affected packages sit under a Red Hat-associated npm scope, and that makes the story more visible. But the pattern is not unique to Red Hat, npm, GitHub Actions, or JavaScript. Any ecosystem that combines automated publishing, repository identity, package-manager lifecycle execution, and privileged CI tokens has the same shape of risk.That includes internal enterprise package feeds. In fact, private registries may be worse in some environments because they receive less external scrutiny. A company may trust its internal packages implicitly, run install scripts freely, and allow broad CI access because the package name begins with the organization’s own scope.
The Red Hat association also underscores why namespace trust is not enough. Developers often treat known scopes as safer than random packages, and usually they are. But “safer” is not “safe,” especially when a compromised upstream pipeline can publish through a legitimate channel.
The most important question for enterprises is not whether they used one of the listed packages. That is the first question, and it must be answered. The second question is whether their own publishing pipelines would fail in the same way if an attacker reached a maintainer workflow.
Windows Shops Are in the Blast Radius Even When Linux Takes the Hit
Microsoft notes that the payload operated across Linux, macOS, and Windows, while Linux CI/CD runners appeared to be the primary target. For Windows-heavy shops, that may sound like a near miss. It is not.Most Windows software teams now depend on JavaScript somewhere: web front ends, admin portals, Electron apps, documentation tooling, test harnesses, build scripts, Teams apps, Azure deployment helpers, or internal dashboards. A compromised npm package can enter the Windows estate through build tooling long before it appears as an endpoint alert on a user’s desktop.
The Windows endpoint also remains a credential cache. Developer machines may hold SSH keys, Git credentials, browser sessions, cloud CLI profiles,
.npmrc files, Docker credentials, Kubernetes configs, and saved tokens for internal systems. Even if the campaign’s most advanced behavior favored Linux runners, Windows workstations can still be the place where the next publish-capable token is found.For defenders using Microsoft Defender XDR or similar tooling, the practical signal is behavioral. Look for unusual lifecycle script execution, Bun downloads from unexpected processes,
node spawning shell and then Bun, access to cloud metadata endpoints from build processes, sudden GitHub repository creation, suspicious npm token validation, and strange commits to non-default branches.Ignore-Scripts Is a Blunt Instrument With a Real Use
One mitigation Microsoft recommends is usingnpm install --ignore-scripts to disable pre- and post-installation script execution. In the abstract, that advice is easy. In real projects, it can break things. Some packages use lifecycle scripts for native builds, postinstall setup, or legitimate generation steps.That does not make the recommendation useless. It means organizations should distinguish between developer convenience and build-system policy. A hardened CI path for dependency resolution can use
ignore-scripts during audit, lockfile generation, or mirror ingestion, then permit scripts only in controlled stages where behavior is monitored and expected.Dependency pinning is similarly unglamorous but important. Automatic upgrades are convenient until the update stream becomes the infection stream. Pinning known-good versions, validating lockfiles, and delaying automatic adoption of new package versions can turn a fast-moving supply-chain incident from an immediate compromise into an alertable discrepancy.
The deeper mitigation is to reduce the authority available to any one job. A build that installs dependencies should not automatically have the right to publish packages, rewrite repositories, read organization secrets, and reach cloud metadata services unless the workflow genuinely requires it. Least privilege is tedious until the alternative is a worm with a registry account.
The Real Fix Is Treating Build Systems Like Production Systems
For years, many organizations treated CI/CD as backstage infrastructure. Production got monitoring, segmentation, change control, and incident response. Build runners got speed, convenience, broad secrets, and a shrug.That distinction no longer survives contact with modern supply-chain attacks. A build runner can publish production code. A package workflow can mint trusted artifacts. A repository token can change what thousands of downstream systems consume. In practical terms, CI/CD is production infrastructure with a better disguise.
That means build environments need the same seriousness applied to servers handling customer data. Runners should be ephemeral where possible. Secrets should be scoped, short-lived, and bound to specific workflows. Branch protections should matter. Default token permissions should be reduced. Publishing jobs should be separated from test jobs. Outbound network access should be observable and, where feasible, constrained.
Most of all, provenance should be treated as evidence, not absolution. A signed malicious package is still malicious. An attested compromised build is still compromised. The point of these systems is to narrow uncertainty, not eliminate the need for judgment.
The Miasma Lesson Fits in One Uncomfortable Release Note
The Red Hat npm Miasma campaign is a reminder that trusted automation can fail dangerously when trust is granted too broadly and observed too narrowly. The concrete response is not to abandon automation, but to make the path from source to package more inspectable, less privileged, and less forgiving of surprise behavior.- Organizations should inventory direct and transitive use of the affected
@redhat-cloud-servicespackages and identify any systems that installed the malicious versions during the exposure window. - Teams should rotate potentially exposed GitHub, npm, cloud, CI/CD, SSH, Kubernetes, Vault, and developer credentials after isolating suspect hosts and runners.
- Build pipelines should treat unexpected lifecycle scripts, Bun runtime downloads, and
node-to-shell-to-runtime process chains as high-signal events. - Package publishing workflows should be separated from ordinary build and test jobs, with narrow OIDC permissions and strict branch protections.
- Provenance signatures should be used as one layer of assurance, not as a substitute for artifact inspection, runtime monitoring, and pipeline hardening.
- Enterprises should rehearse CI/CD incident response the same way they rehearse endpoint or cloud compromise, because package publishing rights are now production-grade power.
References
- Primary source: Microsoft
Published: 2026-06-03T04:50:21.409752
Preinstall to persistence: Inside the Red Hat npm Miasma credential-stealing campaign | Microsoft Security Blog
A large-scale npm supply chain attack compromised over 90 versions of @redhat-cloud-services packages, silently infecting CI/CD environments and developer systems. The malicious code steals credentials from GitHub, cloud platforms, and local machines, then spreads like a worm by republishing...www.microsoft.com