How a stolen session cookie turned a security certification into a weapon
The packages that hit developers' machines on June 1, 2026 carried a security certificate. Not a forged one. A real, cryptographically valid attestation confirming that the code had been built by Red Hat's own pipeline, signed by a trusted authority, verifiable by any tool in the ecosystem. Every modern supply chain security check passed. The packages were, by every measurable standard, legitimate. They were also backdoored.
This is the core of the Miasma attack: the attacker did not break the security system. They walked through the front door using a stolen key, triggered the legitimate build process, and let Red Hat's own infrastructure sign the malicious packages on their behalf. The certification was accurate. The pipeline really did build those packages. What no certificate can tell you is whether the person who started the pipeline had any right to be there.
The stolen key was a browser session cookie, lifted from a Red Hat employee's device by infostealer malware weeks before a single package was touched. That cookie bypassed multi-factor authentication entirely. It had been sitting on underground markets for approximately seven weeks before anyone used it. By the time the attack ran, 96 backdoored versions of 32 packages had been published, a self-propagating worm was sweeping developer environments for every cloud credential it could find, and the same worm family had already begun a second wave two days later using a technique that bypassed every security tool monitoring for malicious install scripts.
Narrative · 7 min read
The Context
Red Hat is one of the largest enterprise Linux and cloud software companies in the world, owned by IBM. Its Hybrid Cloud Console is the central management interface for products including OpenShift (a Kubernetes platform used by thousands of enterprises), Red Hat Ansible Automation Platform, and managed cloud services on AWS, Azure, and GCP. The console's frontend is built from JavaScript packages published under the @redhat-cloud-services namespace on npm. These packages are build-time dependencies: code pulled into developer and CI environments during software assembly—the moment when a machine holds the most sensitive credentials it will ever touch.
The Attack, Phase by Phase
Phase 1: Credential Harvest and Pre-Positioning
The attack began not with a hack but with a purchase. Weeks before any package was touched, infostealer malware on a Red Hat employee's device exfiltrated the employee's GitHub credentials and an active browser session cookie. Both appeared in underground market logs on April 13, 2026, and again on May 15. Whiteintel, a threat intelligence firm monitoring these markets, detected both appearances and verified the credential belonged to an active Red Hat employee.
The session cookie is the critical detail. It is equivalent to a logged-in session: no password required, no MFA prompt. Whoever held it held authenticated access to the employee's GitHub account. It sat available on underground markets for approximately seven weeks.
On May 29, a test commit containing the string "Miasma: The Spreading Blight" appeared in a RedHatInsights repository. The attacker was staging.
Phase 2: Pipeline Hijack and Malicious Publish
On June 1, the attacker used the stolen session cookie to authenticate as the Red Hat employee and pushed malicious orphan commits to three RedHatInsights repositories across two waves: the first at approximately 10:53 UTC, the second at 13:44 UTC.
Each orphan commit contained two files: a minimal GitHub Actions workflow configured to trigger on any push, and an obfuscated script. The workflow requested a GitHub OIDC identity token and executed the script, which used that token to publish backdoored package versions to npm.
Here is why this worked: orphan commits are not attached to any branch. Branch protection rules require code review before changes can merge—but only on branches. An orphan commit has no branch, so it has no review requirement. The workflow triggered automatically. The OIDC token was issued legitimately, because the request came from inside the real repository's Actions environment. npm accepted the publish. Sigstore signed the SLSA provenance attestation, because the package really was built by that repository's workflow.
The result: 96 backdoored versions of 32 packages, all carrying valid security certifications, published in under three hours.
Phase 3: Install-Time Execution and Credential Sweep
Any developer or CI runner that ran npm install against an affected package version triggered the preinstall hook before a single line of application code executed. The hook ran a 4.29 MB obfuscated dropper—approximately 25 times the expected size of a normal index file—with the payload buried under ROT-based encoding and AES-128-GCM decryption.
Once unpacked, the payload downloaded the Bun JavaScript runtime and launched a comprehensive credential sweep targeting: GitHub Actions tokens, npm tokens, AWS credentials via instance metadata and ECS metadata, Azure OAuth2 tokens, GCP service account tokens, HashiCorp Vault tokens, Kubernetes service account tokens, SSH private keys, Docker registry credentials, GPG keys, CircleCI tokens, and every .env file on the machine. In cloud environments, it actively queried AWS Secrets Manager, Azure Key Vault, and GCP Secret Manager to retrieve secrets the machine had permission to access. It also scraped GitHub Actions runner process memory to extract secrets masked in logs.
The malware included a destructive tripwire: if it detected interaction with a planted decoy token, it executed rm -rf ~/ to wipe the victim's home directory.
Phase 4: Worm Propagation and Ecosystem Spread
Using stolen npm and GitHub OIDC tokens, the malware queried the npm registry for every package the compromised identity could publish, then republished backdoored versions carrying the same payload. Each infected developer with publish rights became a new distribution vector.
For GitHub propagation, the worm enumerated writable repositories, read workflow files via GitHub's GraphQL API, and committed malicious workflows through the createCommitOnBranch mutation. These commits appeared as verified, signed changes.
The worm also injected persistence into AI coding tools: a SessionStart hook into Anthropic Claude Code and a tasks.json with runOn: folderOpen into VS Code projects. Future coding sessions in poisoned projects would re-execute the payload.
On June 3, the same worm family returned with a new technique. A 157-byte binding.gyp file triggered the node-gyp build tool at install time without touching the package.json scripts field. Every security tool monitoring only lifecycle hooks in package.json saw nothing. This "Phantom Gyp" wave compromised 57 additional packages across 286 malicious versions in under two hours, including packages with over 400,000 monthly downloads.
What Made This Possible
-
Session cookies are durable, transferable credentials. A browser session cookie bypasses MFA because authentication already happened when the session was created. Infostealer malware specifically targets these cookies: they work immediately, without any additional step. This credential sat on underground markets for seven weeks undetected.
-
OIDC trusted publishing and SLSA provenance verify process, not actor. Both controls were working exactly as designed. The OIDC token was issued to the correct repository. The provenance attestation accurately recorded the build environment. Neither has any mechanism to verify whether the person who initiated the workflow was authorized to do so. When the attacker authenticated as the employee, every downstream trust signal became accurate and misleading simultaneously.
-
Orphan commits are a blind spot in branch protection. Branch protection rules require review before a branch can merge. Orphan commits have no branch, so the rules do not apply. The malicious workflow files were never reviewed.
The punchline: three independent security improvements—MFA, trusted publishing, and branch protection—each failed not because they were broken, but because they were bypassed at a layer they were never designed to cover.
What Should Have Stopped This
No single control would have prevented this outright. Every defense that would have reduced the blast radius shares one trait: it operates on scope and structure, not on trust in the triggering actor.
- Continuous credential monitoring against infostealer feeds. The stolen session cookie appeared in underground market logs on April 13, seven weeks before the attack. Services monitoring these feeds would have flagged the exposure in time to revoke the session before any package was touched.
- OIDC trust scoped to specific branches, not whole repositories. GitHub OIDC tokens can be configured to issue only when a workflow runs on a named branch. An orphan commit has no branch. Scoping the trust claim to
ref:refs/heads/mainwould have caused npm to reject the publish token entirely. - Blocking install-time scripts in CI. Running
npm install --ignore-scriptsprevents preinstall and postinstall hooks from executing. For packages that genuinely require build steps, an explicit allowlist forces a human decision about which packages may run code at install time. - Least-privilege token scoping on CI runners. A runner that can only read code and run tests cannot publish packages, query cloud secret stores, or commit to other repositories. Scoping permissions to the minimum required limits what a compromised workflow can do.
The Takeaway
Miasma is the same class of failure as the Stryker Intune wipe: a trusted administrative system weaponized against the organization it was built to protect. The meta-pattern: when an attacker can authenticate as a legitimate user, every system that trusts that user's identity becomes an attack surface—including the systems designed to provide security guarantees.
The seven-week gap between credential exposure and attack is not a footnote. It is a parallel systemic failure: the absence of dark-web credential monitoring as a standard supply chain defense. The warning signal existed. It was sitting in a place no one was watching.
Pattern to remember: Process integrity guarantees are only as strong as the identity controls upstream of the process. Certifying that a pipeline ran correctly does not certify that the person who started it had any right to do so.
What changed: Supply chain provenance attestations, previously understood as a defense against tampering, can now be understood as a mechanism that launders attacker actions into trusted artifacts. The attacker did not defeat the attestation system. They used it.
Technical Deep Dive · 5 min
The Technical Mechanism
The Miasma attack chain begins with credential theft via infostealer malware (likely Lumma Stealer or a derivative, based on the exfiltration profile, though the specific infostealer family has not been publicly confirmed). The exfiltrated session cookie was a GitHub browser session token, which GitHub accepts as a valid authentication credential independent of MFA state. Session cookies of this type do not expire on a fixed schedule; they remain valid until explicitly revoked or until the session is terminated server-side.
Orphan commit mechanism: An orphan commit (git commit --orphan) creates a commit object with no parent in the repository's directed acyclic graph. GitHub's branch protection rules evaluate pushes against named refs (branches and tags). Because an orphan commit push creates a new ref that is not subject to existing branch protection policies, the required_pull_request_reviews and required_status_checks constraints do not apply. The attacker pushed to refs outside protected branch scope, triggering the on: push event in the injected workflow.
OIDC token exchange: The injected ci.yaml workflow requested id-token: write permission, causing GitHub Actions to issue a short-lived OIDC JWT signed by GitHub's OIDC provider (token.actions.githubusercontent.com). The JWT's subject claim (sub) encoded the repository and workflow path. npm's trusted publishing configuration for the @redhat-cloud-services scope accepted tokens with a matching sub claim, issuing a publish token scoped to the namespace. The OIDC token exchange is the legitimate mechanism introduced to replace long-lived npm automation tokens; it worked as designed.
SLSA provenance: The GitHub Actions OIDC-based publish flow automatically generates a SLSA Build Level 3 provenance attestation via the slsa-github-generator action. The attestation is signed using Sigstore's Fulcio certificate authority and recorded on the Rekor transparency log. The attestation accurately recorded the repository, workflow, and commit SHA. No field in the SLSA provenance schema records whether the triggering actor was authorized; the schema records what ran, not who authorized it to run.
Payload unpacking: The _index.js dropper (4.29 MB) used a multi-stage deobfuscation chain: ROT-N character substitution (variant per package) followed by AES-128-GCM decryption with a hardcoded key embedded in the obfuscated layer. The final stage downloaded the Bun JavaScript runtime binary from a CDN and executed the credential-harvesting payload in the Bun environment to avoid Node.js-specific detection signatures.
Environment gating: The payload checked Intl.DateTimeFormat().resolvedOptions().timeZone and the number of configured locale regions. Systems with fewer than a threshold number of locales (consistent with sandbox environments) caused the payload to terminate silently. An environment variable (MIASMA_CI_ONLY) optionally restricted execution to environments where CI=true was set, targeting CI runners specifically.
Phantom Gyp technique: The June 3 follow-on wave used a binding.gyp file (157 bytes) in the package root. When npm detects a binding.gyp file, it automatically invokes node-gyp rebuild at install time as a built-in behavior, independent of the scripts field in package.json. Security tools that monitor only preinstall, install, and postinstall hooks in package.json do not observe this execution path. The binding.gyp file contained a minimal valid JSON structure that caused node-gyp to invoke a shell command executing the dropper.
Self-propagation: The worm used the npm search API with the maintainer: filter to enumerate all packages the compromised identity could publish. For each package, it downloaded the latest version, injected the preinstall hook and dropper, and republished using the bypass_2fa=true parameter in the npm publish API, which is available to tokens with sufficient scope and bypasses npm's two-factor authentication requirement for publishing. For GitHub propagation, the worm used the createCommitOnBranch GraphQL mutation with the stolen GitHub token, creating commits that appear as verified changes in the repository's commit history.
CVE and Advisories
No CVE has been assigned to this incident. The attack did not exploit a software vulnerability; it exploited a combination of a compromised credential, a gap in branch protection scope, and a design limitation in provenance attestation schemas.
The official Red Hat security bulletin is RHSB-2026-006, published June 2, 2026.
MITRE ATT&CK Mapping
| Technique ID | ATT&CK name | How it appeared |
|---|---|---|
| T1078 | Valid Accounts | Attacker authenticated to GitHub using a stolen session cookie belonging to a legitimate Red Hat employee, bypassing MFA. |
| T1195.001 | Supply Chain Compromise: Compromise Software Dependencies and Development Tools | Backdoored versions of 32 npm packages published to the registry via the compromised employee's pipeline access. |
| T1059.007 | Command and Scripting Interpreter: JavaScript | Malicious preinstall hook executed a heavily obfuscated JavaScript dropper at install time. |
| T1552.001 | Unsecured Credentials: Credentials in Files | Payload swept for .env files, kubeconfig files, SSH private keys, Docker credentials, and GPG keys. |
| T1552.005 | Unsecured Credentials: Cloud Instance Metadata API | Payload queried AWS IMDS, Azure IMDS, and GCP metadata service to retrieve cloud identity tokens. |
| T1567.001 | Exfiltration Over Web Service: Exfiltration to Code Repository | Stolen credentials encrypted and exfiltrated to attacker-controlled dead-drop repositories on GitHub under account liuende501. |
| T1543 | Create or Modify System Process | Persistence injected via Claude Code SessionStart hook and VS Code tasks.json runOn:folderOpen configuration. |
| T1485 | Data Destruction | Destructive tripwire executed rm -rf ~/ upon detection of interaction with a planted decoy token. |
| T1036.001 | Masquerading: Invalid Code Signature | Inverse application: valid SLSA provenance attestations were generated for malicious packages, making them appear legitimate to verification tooling. |
Indicators of Compromise
Attacker Infrastructure
Attacker-controlled GitHub account: liuende501 (236+ dead-drop repositories identified by StepSecurity as of June 4, 2026).
Malware marker string: Miasma: The Spreading Blight (present in early staging commits from May 29, 2026).
File Indicators
Dropper size anomaly: A _index.js or equivalent preinstall script of approximately 4.29 MB in any npm package is a strong indicator. Normal index files for frontend component libraries are typically under 200 KB.
Affected npm scope: All packages under @redhat-cloud-services published between approximately 10:53 UTC and 14:00 UTC on June 1, 2026 should be treated as potentially compromised. Red Hat engineering removed the malicious versions; verify your lock file does not pin any version from this window.
Phantom Gyp indicator: Presence of a binding.gyp file in a JavaScript package that has no native C/C++ components and no legitimate reason to invoke node-gyp.
Network Indicators
Outbound connections to api.github.com from CI runners during the npm install phase (outside of expected workflow steps) may indicate worm propagation activity. The payload also contacted CDN endpoints to download the Bun runtime binary; the specific URLs rotated across waves and are documented in the Wiz and StepSecurity advisories linked below.
Detection Difficulty
The multi-layer obfuscation (ROT + AES-128-GCM) and environment gating (sandbox termination, CI-only mode) make static analysis and sandbox detonation unreliable. The SLSA provenance attestation on affected packages passes standard verification. The most reliable detection signal is the dropper file size anomaly and the presence of binding.gyp in packages with no native dependencies.
Attribution
Attribution is unconfirmed. The Miasma payload is a derivative of the Mini Shai-Hulud worm, developed and open-sourced by the threat actor group TeamPCP (also tracked as Replicating Marauder, TGR-CRI-1135, UNC6780 by Google Threat Intelligence, DeadCatx3, PCPcat, ShellForce, and CipherForce by Snyk and Palo Alto Networks Unit 42). TeamPCP is assessed as a financially motivated group that emerged in late 2025.
On May 12, 2026, TeamPCP published the full Mini Shai-Hulud source code to GitHub and advertised it on BreachForums. GitHub removed the repository shortly after, but multiple forks had already been created. Wiz Research describes the Miasma modifications as "largely cosmetic," with Dune universe references replaced by Greek mythology themes while the underlying mechanics remain substantially identical. Both Wiz and Palo Alto Networks Unit 42 explicitly treat the TTP overlap as insufficient for definitive attribution, noting that the public release of the source code means any competent actor can replicate the same attack. No nation-state link has been assessed by any firm.
Primary Sources
- 01.Miasma: Supply Chain Attack Targeting RedHat npm Packages
Wiz Research · June 1, 2026
- 02.RHSB-2026-006 Supply chain compromise of @redhat-cloud-services npm packages
Red Hat Product Security · June 2, 2026
- 03.Preinstall to persistence: Inside the Red Hat npm Miasma credential-stealing campaign
Microsoft Threat Intelligence · June 2, 2026
- 04.Multiple redhat-cloud-services npm Packages compromised
StepSecurity · June 1, 2026
- 05.Miasma npm Supply Chain Attack: Self-Spreading Worm via Phantom Gyp
StepSecurity · June 4, 2026
- 06.Miasma Attack Hits Red Hat npm Packages
Snyk Security · June 1, 2026
- 07.Red Hat Miasma Attack: A Linked GitHub Credential Surfaced in Stealer Logs
Whiteintel · June 1, 2026
- 08.Miasma Supply Chain Attack Compromises Red Hat npm Packages with Credential-Stealing Worm
The Hacker News · June 2, 2026