Contents
ToggleExecutive Summary
On June 1, 2026, 32 packages in the @redhat-cloud-services npm scope published malicious versions carrying a credential-stealing worm called Miasma. Combined, those packages accumulate 116,991 downloads per week. The attack went live in two distinct publication waves starting at 10:54 UTC and 13:45 UTC, with 96 compromised versions published before detection. Both Socket and Aikido flagged malicious releases within the first hour. StepSecurity and Aikido have filed disclosure issues in the three upstream Red Hat repositories involved.
The entry point was a compromised Red Hat employee GitHub account. The attacker pushed orphan commits directly to several repositories, bypassing code review, and included a GitHub Actions workflow that requested short-lived OIDC tokens via GitHub’s Trusted Publishing mechanism. Those tokens were used to publish backdoored versions across every package the compromised workflow had publish access to. The mechanism bypasses npm’s standard long-lived token protections entirely, because the tokens used were legitimate, short-lived, OIDC-issued credentials.
Miasma is structurally a Mini Shai-Hulud derivative. The payload self-identifies as “Miasma: The Spreading Blight” and replaces the Dune mythology of the Shai-Hulud lineage with Greek mythology references. The technical architecture is unchanged in the ways that matter: four-layer obfuscation, AES-GCM encrypted embedded payloads executed via Bun, broad credential sweeps covering 30+ credential paths, GitHub Actions runner memory extraction targeting masked secrets, dual-channel exfiltration over HTTPS and GitHub’s Contents API, and a worm propagation mechanism using stolen npm tokens with bypass_2fa: true. No CVE has been assigned. Traditional CVE-driven scanners have no detection surface for this class of incident.
Zero-CVE Gap. No CVE, GHSA, or OSV record exists for any Miasma-compromised package. Every malicious release was published using legitimate OIDC-issued npm credentials that passed Trusted Publishing validation. Scanner workflows dependent on CVE assignment had no detection surface during the active exposure window.
TL;DR for Engineering Teams
| What it is | Coordinated npm supply chain compromise of 32 packages in the @redhat-cloud-services scope, delivering a Bun-executed credential stealer branded “Miasma: The Spreading Blight.” Structural variant of Mini Shai-Hulud. No CVE assigned. 96 malicious versions across two waves on June 1, 2026. |
| Where it bites | Any environment that ran npm install against an affected @redhat-cloud-services package version on or after June 1, 2026 at 10:54 UTC. The preinstall hook fires before any application code executes. Transitive lockfile dependencies count. Phoenix Security malware intelligence flagged frontend-components-config-utilities@4.11.3 with LLM analyst confidence 98 (MALICIOUS): install-hook-abuse (CS-002), credential-harvesting (RS-001), payload-download (NS-002), HTTP POST exfiltration (NS-004). |
| Why it matters | The payload reads /proc/{pid}/mem of the GitHub Actions Runner.Worker process to extract masked secrets that never appear in logs. It sweeps AWS, GCP, Azure, Kubernetes, HashiCorp Vault, SSH keys, npm tokens, Docker credentials, and .env files. Stolen npm tokens are used with bypass_2fa: true to self-propagate. All initial publishes used legitimate OIDC-issued tokens, meaning provenance checks pass on every malicious release. |
| Patch status | No clean successor versions confirmed at time of writing. Revert lockfiles to the last known-clean version per package. Do not run npm install or npm update against the @redhat-cloud-services scope until Red Hat confirms pipeline integrity. |
| Immediate action | Search all lockfiles for affected versions. If any affected version installed on or after June 1, rotate all credentials immediately: GitHub tokens, AWS/GCP/Azure credentials, npm tokens, Kubernetes service account tokens, HashiCorp Vault tokens, SSH keys, and Docker credentials. Set npm config set ignore-scripts true on all CI runners. |
Vulnerability Overview
| Vendor | Red Hat (Red Hat Cloud Services / RedHatInsights) |
| Products | 32 packages in the @redhat-cloud-services npm scope |
| Vulnerability Type | Supply chain compromise; credential theft; self-propagating npm worm |
| CWE | CWE-829 (Inclusion of Functionality from Untrusted Control Sphere); CWE-506 (Embedded Malicious Code) |
| CVSS | Not assigned |
| CVE | Not assigned |
| GHSA / OSV | Not assigned at time of writing |
| Attack Vector | Network (npm install preinstall hook execution) |
| Active Exploitation | Confirmed |
| Attribution | Miasma variant of Shai-Hulud lineage; self-branded “Miasma: The Spreading Blight”; Greek mythology references replace prior Dune references; open-sourced TeamPCP tooling basis |
| Publish Mechanism | GitHub Actions OIDC Trusted Publishing via compromised Red Hat employee GitHub account |
| Exposure Window | June 1, 2026, 10:54 UTC onward |
| Upstream Repos | RedHatInsights/javascript-clients, RedHatInsights/frontend-components, RedHatInsights/platform-frontend-ai-toolkit |

Technical Anatomy
Root Cause: Compromised GitHub Account + Trusted Publishing Misuse
A Red Hat employee’s GitHub account was compromised and used to push orphan commits directly to repositories in the RedHatInsights organization. Orphan commits sit outside the standard pull request workflow and bypass code review entirely. The commits introduced two files: a GitHub Actions workflow (ci.yaml) and a JavaScript launcher (_index.js).
The workflow requested id-token: write permissions, allowing it to obtain a short-lived OIDC token from GitHub during execution. It passed a list of target package names to _index.js via the OIDC_PACKAGES environment variable. The script exchanged the OIDC token for npm publish credentials through the Trusted Publishing endpoint and published backdoored versions of all listed packages simultaneously.
name: releaseon: push: branches: ['*']jobs: release: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd - uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 - name: prepare run: bun run _index.js env: OIDC_PACKAGES: "@redhat-cloud-services/frontend-components-advisor-components, ..." WORKFLOW_ID: "ci.yaml" REPO_ID_SUFFIX: "RedHatInsights/frontend-components"
This is the same pattern documented in prior Shai-Hulud attacks against TanStack and Bitwarden CLI: the CI/CD pipeline becomes the attack surface, and OIDC Trusted Publishing becomes the credential source for mass unauthorized publication.

Exploit Path
Step 1 — Entry point. The attacker compromises a Red Hat employee GitHub account and pushes orphan commits to RedHatInsights repositories. No pull request review applies. The injected workflow and _index.js are the only additions.
Step 2 — Vulnerability trigger. When the injected workflow runs, GitHub issues a valid OIDC JWT for the RedHatInsights/frontend-components identity. The _index.js script exchanges this against npm’s /v1/oidc/token/exchange/package/ endpoint. Every package listed in OIDC_PACKAGES that has the workflow’s repository identity registered as a trusted publisher accepts the token. No long-lived npm secrets are required and none are stolen at this stage.
Step 3 — Execution impact. Each compromised tarball contains a preinstall lifecycle hook running node index.js automatically on every npm install, before any application code executes. The 4.2 MB index.js is four-layer obfuscated: ROT-21 encoding, AES-128-GCM encrypted blobs, an obfuscator.io string table with 284-cycle rotation, and a custom B5 cipher for sensitive strings. At runtime it decrypts two payloads: a Bun downloader and the main implant. The implant is written to a randomized /tmp/p*.js path, executed with Bun, then deleted. On developer workstations, the payload daemonizes before executing.
Obfuscation Layers
| Layer | Technique | Purpose |
| Layer 1 | ROT-21 Caesar cipher + char-code array + eval | Bypasses basic string search; silent catch block hides errors |
| Layer 2 | AES-128-GCM encrypted blobs (_b and _p) | Hides Bun downloader and main implant from static analysis |
| Layer 3 | obfuscator.io custom base64 + 284-cycle IIFE rotation | Defeats static string extraction without runtime simulation |
| Layer 4 | B5 cipher: PBKDF2 200K iterations + Fisher-Yates substitution | Protects C2 endpoints, file paths; brute-force infeasible |
Payload Capabilities
Runner memory extraction. The payload queries the GitHub Actions runtime API using ACTIONS_RUNTIME_TOKEN to enumerate variables flagged isSecret: true, then reads those values directly from /proc/{pid}/mem of the Runner.Worker process. This extracts masked secrets that never appear in workflow logs.
Credential sweep targets:
| Target | Credentials |
| GitHub Actions | GITHUB_TOKEN, ACTIONS_RUNTIME_TOKEN, ACTIONS_ID_TOKEN_REQUEST_TOKEN, NPM_TOKEN |
| AWS | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, ~/.aws/credentials |
| GCP | Application default credentials, service account key files |
| Azure | AZURE_CLIENT_SECRET, managed identity tokens, ~/.azure/accessTokens.json |
| HashiCorp Vault | VAULT_TOKEN, VAULT_ADDR |
| Kubernetes | In-cluster service account token, ~/.kube/config |
| npm | ~/.npmrc publish tokens |
| SSH | ~/.ssh/id_rsa, ~/.ssh/id_ed25519, all private key files |
| Docker | ~/.docker/config.json |
| General | .env, .env.local, .env.production, .pypirc, .netrc, .git-credentials |
Self-propagating worm. Using harvested npm tokens, the payload enumerates packages the victim account can publish and republishes backdoored versions using bypass_2fa: true. Every infected CI runner is a potential source of downstream compromise.
Developer workstation persistence. On non-CI systems, the payload injects SessionStart hooks into ~/.claude/settings.json (executes at every Claude Code session start) and folderOpen tasks into .vscode/tasks.json (executes when the developer opens a project in VS Code). Both persist after npm uninstall.
Dual-channel exfiltration. Primary channel: stolen data gzip-compressed, AES-256-GCM encrypted with RSA-wrapped per-session key, sent via HTTPS POST. Fallback channel: GitHub Contents API commits writing results-{timestamp}-{counter}.json into victim repositories, with commit messages containing IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner:{token}. This routes exfiltrated data through api.github.com.
Anti-analysis. The payload checks Russian locale via Intl.DateTimeFormat, LC_ALL, LC_MESSAGES, and LANG, exiting without executing on matching systems. It also detects canary tokens and security tooling.
C2 infrastructure. All C2 traffic uses https://api.github.com with User-Agent: python-requests/2.31.0. The attacker operates a 16-account pool: typhonian, tartarean, erebean, stygian, orphic, nemean, spartan, basilisk, manticore, styx, aegis, thunderbolt, tempest, cataclysm, onslaught, havoc. One account is selected randomly per session.
Connection to TeamPCP / Shai-Hulud Lineage
TeamPCP published the full Mini Shai-Hulud source code to GitHub on May 12, 2026, alongside BreachForums posts encouraging independent campaigns. The Miasma payload is structurally consistent with that open-sourced tooling: four-layer obfuscation stack, Bun-as-runtime, AES-GCM payload staging through /tmp, bypass_2fa: true worm propagation, runner memory extraction via /proc/mem, and AI coding agent persistence targeting .claude/settings.json.
The rebranding from Dune to Greek mythology references is the primary distinguishing marker. Attribution beyond “derived from open-sourced TeamPCP tooling” cannot be confirmed from public evidence. The open-sourcing event means any operator can now run structurally identical campaigns against new target ecosystems.
Affected Versions
96 malicious versions across 32 packages in the @redhat-cloud-services npm scope. Combined weekly downloads: 116,991. Exposure window begins June 1, 2026 at 10:54 UTC.
| Package | Compromised Versions | Last Known-Clean |
| @redhat-cloud-services/chrome | 2.3.1, 2.3.2, 2.3.4 | 2.3.0 |
| @redhat-cloud-services/compliance-client | 4.0.3, 4.0.4, 4.0.6 | 4.0.2 |
| @redhat-cloud-services/config-manager-client | 5.0.4, 5.0.5, 5.0.7 | 5.0.3 |
| @redhat-cloud-services/entitlements-client | 4.0.11, 4.0.12, 4.0.14 | 4.0.10 |
| @redhat-cloud-services/eslint-config-redhat-cloud-services | 3.2.1, 3.2.2, 3.2.4 | 3.2.0 |
| @redhat-cloud-services/frontend-components | 7.7.2, 7.7.3, 7.7.5 | 7.7.1 |
| @redhat-cloud-services/frontend-components-advisor-components | 3.8.2, 3.8.4, 3.8.6 | 3.8.1 |
| @redhat-cloud-services/frontend-components-config | 6.11.3, 6.11.4, 6.11.6 | 6.11.2 |
| @redhat-cloud-services/frontend-components-config-utilities | 4.11.2, 4.11.3, 4.11.5 | 4.11.1 |
| @redhat-cloud-services/frontend-components-notifications | 6.9.2, 6.9.3, 6.9.5 | 6.9.1 |
| @redhat-cloud-services/frontend-components-remediations | 4.9.2, 4.9.3, 4.9.5 | 4.9.1 |
| @redhat-cloud-services/frontend-components-testing | 1.2.1, 1.2.2, 1.2.4 | 1.2.0 |
| @redhat-cloud-services/frontend-components-translations | 4.4.1, 4.4.2, 4.4.4 | 4.4.0 |
| @redhat-cloud-services/frontend-components-utilities | 7.4.1, 7.4.2, 7.4.4 | 7.4.0 |
| @redhat-cloud-services/hcc-feo-mcp | 0.3.1, 0.3.2, 0.3.4 | 0.3.0 |
| @redhat-cloud-services/hcc-kessel-mcp | 0.3.1, 0.3.2, 0.3.4 | 0.3.0 |
| @redhat-cloud-services/hcc-pf-mcp | 0.6.1, 0.6.2, 0.6.4 | 0.6.0 |
| @redhat-cloud-services/host-inventory-client | 5.0.3, 5.0.4, 5.0.6 | 5.0.2 |
| @redhat-cloud-services/insights-client | 4.0.4, 4.0.5, 4.0.7 | 4.0.3 |
| @redhat-cloud-services/integrations-client | 6.0.4, 6.0.5, 6.0.7 | 6.0.3 |
| @redhat-cloud-services/javascript-clients-shared | 2.0.8, 2.0.9, 2.0.11 | 2.0.7 |
| @redhat-cloud-services/notifications-client | 6.1.4, 6.1.5, 6.1.7 | 6.1.3 |
| @redhat-cloud-services/patch-client | 4.0.4, 4.0.5, 4.0.7 | 4.0.3 |
| @redhat-cloud-services/quickstarts-client | 4.0.11, 4.0.12, 4.0.14 | 4.0.10 |
| @redhat-cloud-services/rbac-client | 9.0.3, 9.0.4, 9.0.6 | 9.0.2 |
| @redhat-cloud-services/remediations-client | 4.0.4, 4.0.5, 4.0.7 | 4.0.3 |
| @redhat-cloud-services/rule-components | 4.7.2, 4.7.3, 4.7.5 | 4.7.1 |
| @redhat-cloud-services/sources-client | 3.0.10, 3.0.11, 3.0.13 | 3.0.9 |
| @redhat-cloud-services/topological-inventory-client | 3.0.10, 3.0.11, 3.0.13 | 3.0.9 |
| @redhat-cloud-services/tsc-transform-imports | 1.2.2, 1.2.4, 1.2.6 | 1.2.1 |
| @redhat-cloud-services/types | 3.6.1, 3.6.2, 3.6.4 | 3.6.0 |
| @redhat-cloud-services/vulnerabilities-client | 2.1.8, 2.1.9, 2.1.11 | 2.1.7 |
Exposure Analysis
| Environment | Risk Level | Reason |
| CI/CD pipelines (GitHub Actions) | Critical | Preinstall hook fires automatically; runner memory extraction pulls masked secrets; OIDC token harvesting enables downstream package compromise |
| Developer workstations | Critical | Daemonized payload runs post-install; Claude Code and VS Code persistence survives package removal; credential sweep covers all local secrets |
| Container builds using Red Hat tooling | High | Any container build running npm install against affected versions executes the payload; credentials baked into build environments are in scope |
| Kubernetes environments | High | Service account tokens and kubeconfig files targeted; lateral movement to cluster workloads possible with harvested credentials |
| Pipelines using –ignore-scripts | Not affected | The preinstall hook is the sole delivery mechanism. npm config set ignore-scripts true blocks the entire chain |
The @redhat-cloud-services scope is used heavily in Red Hat’s Hybrid Cloud Console (HCC) frontend ecosystem and Insights client integrations. Organizations running Red Hat OpenShift, RHEL management tooling, or contributing to the HCC frontend are the primary exposure population. At 116,991 weekly downloads across 32 packages, the potential installation base before detection was significant.
Real-World Impact
The compromised packages cover Red Hat’s core frontend component library, all Insights-platform API client packages, and three MCP (Model Context Protocol) packages added to the Red Hat portfolio in 2026. Any Red Hat partner, managed service provider, or enterprise customer whose CI pipelines pulled npm install against the affected scope on June 1 is potentially exposed.
The self-propagation characteristic makes the blast radius non-linear. A single CI runner with access to any npm token with publish rights could seed backdoored versions into additional package namespaces outside the @redhat-cloud-services scope before detection. StepSecurity’s analysis confirmed the bypass_2fa: true publish path was present and functional in this payload.
StepSecurity’s runtime analysis using Harden-Runner confirmed that the payload reads /proc/{pid}/mem for the Runner.Worker process, extracting masked secrets that do not appear in workflow logs. On developer workstations, the process daemonizes and continues executing after npm install completes.
The attacker’s 16-account Greek mythology-themed C2 pool was designed so that removing any single account does not disrupt operations.
Campaign Timeline
| Date | Event |
| April 22, 2026 | @bitwarden/cli compromised via poisoned GitHub Actions workflow. Payload self-identifies as “Shai-Hulud: The Third Coming” |
| April 29, 2026 | Four SAP CAP npm packages compromised via npm token leaked in CircleCI pull request build |
| April 30, 2026 | PyTorch Lightning compromised on PyPI, versions 2.6.2 and 2.6.3 |
| May 12, 2026 | Mini Shai-Hulud hits 160+ packages including Mistral and TanStack. 645 malicious package artifacts. |
| May 12, 2026 | TeamPCP publishes full Shai-Hulud source code to GitHub. Posts on BreachForums invite others to run independent campaigns. |
| May 19, 2026 | Microsoft’s DurableTask npm package compromised via previously compromised GitHub account |
| June 1, 2026 | Miasma: 32 @redhat-cloud-services packages compromised. 96 malicious versions across two publication waves. 116,991 weekly downloads affected. |
Detection Guidance
Phoenix Security Malware Intelligence Platform
Phoenix Security’s malware intelligence platform flagged @redhat-cloud-services/frontend-components-config-utilities@4.11.3 with a combined heuristic and LLM analyst score of 92, triggering six signals: install-hook-abuse (CS-002, CRITICAL), dynamic-module-import (CS-008, MEDIUM), credential-harvesting (RS-001, CRITICAL), payload-download (NS-002, CRITICAL), HTTP-POST-exfiltration (NS-004, CRITICAL), and unencrypted-communication (NS-008, HIGH). tsc-transform-imports@1.2.4 triggered install-hook-abuse (CS-002) and credential-harvesting (RS-001).
Full signal data: https://phxintel.security/malware.html
Log Indicators
npm install execution artifacts:
- Process execution: node index.js during an npm lifecycle step
- Process execution: bun run /tmp/p*.js
- File creation: /tmp/p{random}.js, /tmp/b-*/bun, /tmp/b-*/b.zip
- Lock file presence: tmp.0987654321.lock
- Process flag: __IS_DAEMON environment variable set on a spawned node process
Network indicators (unexpected during npm install):
- Outbound to api.github.com with User-Agent: python-requests/2.31.0
- Outbound to https://github.com/oven-sh/bun/releases/download/bun-v1.3.13/
- Outbound to https://registry.npmjs.org/-/npm/v1/tokens
- Outbound to http://169.254.169.254/latest/meta-data/iam/security-credentials/ from CI runner
- Outbound to https://secretmanager.googleapis.com
GitHub repository artifacts:
- Files matching results-{timestamp}-{counter}.json in any repository
- Commit messages containing IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner
- Unexpected changes to ~/.claude/settings.json or .vscode/tasks.json
Code and string indicators:
| Indicator | Context |
| Miasma: The Spreading Blight | Primary campaign self-identification string |
| IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner | GitHub API fallback exfiltration commit message prefix |
| thebeautifulmarchoftime | Internal string table marker |
| f4abccab2 | Custom decryption function identifier |
| “preinstall”:”node index.js” | Malicious package.json preinstall hook pattern |
| createDecipheriv(“aes-128-gcm” | Stage 2 AES-GCM decryption function signature |
| createCipheriv(“aes-256-gcm” | Exfiltration encryption function signature |
Verification Steps for Teams
- Search all package-lock.json, yarn.lock, pnpm-lock.yaml, and npm-shrinkwrap.json files across all repositories for any package name in the affected list at a compromised version.
- Check CI logs for any workflow that ran npm install on or after June 1, 2026, 10:54 UTC and resolved any affected package.
- On developer workstations, check for tmp.0987654321.lock, /tmp/p*.js, and Bun binaries in /tmp/b-* directories.
- Search GitHub organization activity for commits containing IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner.
- Check ~/.claude/settings.json for unexpected SessionStart entries and .vscode/tasks.json for unexpected folderOpen tasks in any project directory.
- Run SBOM analysis across container images built after June 1, 2026, for affected package versions.
Remediation Guidance
Immediate Actions
- Set npm config set ignore-scripts true on all CI runners. This blocks the preinstall hook before the credential harvest executes. Validate that this does not break legitimate postinstall scripts in other dependencies before deploying.
- Remove all affected @redhat-cloud-services package versions from project dependencies and lockfiles. Cached tarballs in CI runner package caches and private registries need explicit removal.
- Rotate all credentials accessible to any environment that executed an affected package version: GitHub PATs, npm publish tokens, AWS access keys, GCP service account keys, Azure service principal credentials, HashiCorp Vault tokens, Kubernetes service account tokens, SSH private keys, Docker registry credentials.
- Audit and clean developer workstation persistence artifacts: remove unexpected SessionStart hooks from ~/.claude/settings.json, remove unexpected folderOpen tasks from .vscode/tasks.json, remove tmp.0987654321.lock and /tmp/b-* Bun directories.
- Revoke and re-examine GitHub Actions OIDC Trusted Publishing bindings for any packages in affected repositories. Do not re-establish federation until Red Hat confirms CI pipeline integrity in all three affected repositories.
Mitigations if Patching Is Delayed
- Pin lockfiles to the last known-clean version per package. Do not use npm update or npm install without explicit version pinning against the @redhat-cloud-services scope until clean releases are confirmed.
- Deploy network egress controls on CI runners blocking unexpected outbound connections during npm install steps.
- Add npm package cooldown enforcement via private registry proxies. Require newly published versions to pass a review period before being served to CI pipelines.
- Use StepSecurity Harden-Runner in audit mode on GitHub Actions workflows using @redhat-cloud-services packages to capture runtime process and network events.
Phoenix Intelligence: Package Signal Analysis
Phoenix Security’s malware intelligence platform detected multiple @redhat-cloud-services packages within the first hour of publication on June 1, 2026. The examples below show how the multi-stage signal pipeline surfaces different aspects of the Miasma payload across package types: from the high-signal utility library to the MCP package carrying a dynamic C2 pattern.
Each detection runs through five pipeline stages: Heuristic scoring (static analysis), LLM Analyst (behavioral interpretation), Judge (confidence assessment), Verifier (cross-validation), and Consensus (final verdict). The signal taxonomy covers code (CS-*), reconnaissance (RS-*), and network (NS-*) categories. All three packages below reached MALICIOUS verdict through independent signal chains.
Package 1 — frontend-components-config-utilities@4.11.3
Detection: 2026-06-01 13:48Z | Heuristic score: 92 | LLM Analyst: MALICIOUS (confidence 98%) | Scan ID: 74a4121b
This package triggered the highest signal density in the campaign: 10 bad signals against 85 evaluated, composite score 92. The LLM Analyst flagged it as an info-stealer and dropper based on the combination of install hook execution, dynamic imports, credential access, payload retrieval, and outbound exfiltration. The six triggered signals form a complete attack chain: preinstall hook (CS-002) as the delivery vehicle, dynamic module import (CS-008) enabling the obfuscated multi-stage loader, credential harvesting (RS-001) as the primary collection objective, payload download (NS-002) staging the Bun runtime from GitHub, HTTP POST exfiltration (NS-004) shipping the encrypted results, and unencrypted communication (NS-008) exposing the secondary channel.
| Signal | ID | Severity | Category | File Evidence / Behavior |
| install-hook-abuse | CS-002 | CRITICAL | code | preinstall script in package.json — executes node index.js before install completes |
| dynamic-module-import | CS-008 | MEDIUM | code | require(variable) / computed imports — hides payload path from static analysis |
| credential-harvesting | RS-001 | CRITICAL | reconnaissance | AWS_*, GITHUB_TOKEN, SSH keys, .npmrc, .aws/credentials — broad cloud and developer sweep |
| payload-download | NS-002 | CRITICAL | network | Bun runtime staged from github.com/oven-sh/bun/releases/download/bun-v1.3.13/ |
| http-post-exfiltration | NS-004 | CRITICAL | network | Encrypted credential bundle via HTTPS POST — AES-256-GCM with RSA-wrapped key |
| unencrypted-communication | NS-008 | HIGH | network | http:// to external hosts — secondary exfiltration and cloud metadata endpoint queries |
LLM Analyst Output (conf. 98%) Multiple critical signals indicate malicious intent. The package attempts credential harvesting (RS-001) and exfiltrates environment variables via unencrypted HTTP (NS-004, NS-008). It also attempts to download additional payloads (NS-002), potentially triggered by an install hook (CS-002). Dynamic imports (CS-008) further suggest complex, potentially hidden, malicious logic. The combination points to an info-stealer and dropper.
Package 2 — tsc-transform-imports@1.2.4 and 1.2.2
Detection: 13:49Z (1.2.4) / 11:05Z (1.2.2) | Heuristic score: 20 | LLM Analyst: MALICIOUS (95-97%) | Judge: INCONCLUSIVE | Scan IDs: 588fec99 / d21c4fb8
The tsc-transform-imports package shows a different signal profile. Heuristic score is 20 — low — because the primary malicious logic is embedded in directories.js rather than index.js, so the static scanner has less surface to match against. Despite that, the LLM Analyst reached MALICIOUS at 95-97% confidence on just two signals: the preinstall hook as the trigger, and credential harvesting evidence in directories.js specifically. The Judge returned INCONCLUSIVE on both versions, reflecting reduced statistical confidence when the heuristic layer is weak even though the behavioral reading is clear.
The important principle here: a low heuristic score does not mean low risk. The payload is structurally identical across all 32 packages in this campaign. The difference is which file the malicious code lands in and how much of it is visible before runtime decryption. A package scoring 20 on heuristics with a 97% MALICIOUS LLM verdict warrants identical response to one scoring 92.
| Signal | ID | Severity | Evidence File | Finding |
| install-hook-abuse | CS-002 | CRITICAL | package.json | Install hook: preinstall script present |
| credential-harvesting | RS-001 | CRITICAL | directories.js | Credential harvesting (env vars/tokens) — GITHUB_TOKEN, AWS_*, SSH key access patterns |
Package 3 — hcc-pf-mcp@0.6.1
Detection: 2026-06-01 11:04Z | Heuristic score: 16 | LLM Analyst: MALICIOUS (97%) | Status: confirmed_malicious | Scan ID: c30c5f68
The hcc-pf-mcp package is the most technically distinct detection case. Heuristic score 16 — the lowest in the sample — yet MALICIOUS at 97% confidence. More significantly, the second signal is not credential harvesting but dga-dynamic-c2 (NS-012): a domain generation algorithm or high-entropy DNS resolution pattern found in dist/lib/utils/exportScanner.js.
The DGA signal in exportScanner.js suggests this variant implements a fallback C2 resolution mechanism. Rather than hardcoding attacker infrastructure into the payload — which static string matching catches — the C2 endpoint is computed at runtime from date or hash seeds, producing high-entropy domain targets that rotate per execution. This is complementary to the 16-account pool randomization seen in the primary payload: both techniques are designed to make infrastructure-level blocking insufficient.
hcc-pf-mcp is one of three Red Hat MCP packages in the compromised scope (alongside hcc-feo-mcp and hcc-kessel-mcp). These packages are invoked in AI assistant workflows with access to code, filesystem, and potentially cloud management APIs. Their inclusion in the OIDC_PACKAGES list suggests deliberate selection rather than scope-wide opportunism.
| Signal | ID | Severity | Evidence File | Finding |
| install-hook-abuse | CS-002 | CRITICAL | package.json | Install hook: preinstall script present |
| dga-dynamic-c2 | NS-012 | MEDIUM | dist/lib/utils/exportScanner.js | Domain generation using date/hash seeds — high-entropy DNS targets; C2 endpoint computed at runtime |
The confirmed_malicious status on hcc-pf-mcp@0.6.1 reflects earlier detection — published in the first wave at 10:54Z, it had completed more pipeline stages by the time of analysis. All three MCP packages across versions 0.3.1, 0.3.2, 0.6.1, and 0.6.2 are confirmed malicious and covered in the IOC table.
Signal Pattern Summary Across the Campaign
Across all 32 affected packages, CS-002 (install-hook-abuse) is the universal trigger. It is the one signal that fires on every compromised version regardless of obfuscation depth or which secondary file carries the payload. RS-001 (credential-harvesting) appears when the static scanner indexes the file containing harvested credential paths before runtime decryption. The composite score reflects scanner coverage, not payload severity.
| Package | Ver. | Score | Signals | LLM Verdict | Key Evidence File |
| frontend-components-config-utilities | 4.11.3 | 92 | CS-002, CS-008, RS-001, NS-002, NS-004, NS-008 | MALICIOUS 98% | index.js |
| tsc-transform-imports | 1.2.4 | 20 | CS-002, RS-001 | MALICIOUS 95% | directories.js |
| tsc-transform-imports | 1.2.2 | 20 | CS-002, RS-001 | MALICIOUS 97% | directories.js |
| hcc-pf-mcp | 0.6.1 | 16 | CS-002, NS-012 | MALICIOUS 97% | exportScanner.js |
Detection Principle. CS-002 (install-hook-abuse) on any @redhat-cloud-services package version published June 1, 2026 is sufficient for MALICIOUS classification regardless of composite score. The heuristic score measures how much of the payload surface the static scanner sees before runtime decryption — it does not measure payload severity. Score 16 and score 92 packages carry the same credential-stealing implant.
Protect yourself with the latest threat intelligence, get access to PHOENIX BLUE Today
Indicators of Compromise
SHA-256 Hashes
| Package / Artifact | SHA-256 |
| @redhat-cloud-services/chrome@2.3.1 (tarball) | 88896d478986d453f5da79b311de39d9b4b1bea95c21af1d8ef181b0f4e52fe9 |
| @redhat-cloud-services/chrome@2.3.1 (index.js) | 21b6409a7b84446310daca5409ad6112ac60a1e4bef97736e53fff5f63bfdef4 |
| @redhat-cloud-services/chrome@2.3.1 (package.json) | ee262510cb246d2b904991aee7fc61162bdae34463439ec6383bd5356479d362 |
| Decrypted Bun helper (_b) | ac2a2208e1726e008be6c73dc0872d9bba163319259dff1b62055ac933ca46b6 |
| Decrypted main payload (_p) | 0dc06ecdaa63fe24859cfd955053c23245c536e4733480239d14bebf12688e35 |
| AES-128-GCM key for _b (Bun helper) | Key: 4c26cf9791bce1bfd4b84eba80ce2754 / IV: 1241582f04234f7192feacba |
| AES-128-GCM key for _p (main payload) | Key: ec514c074caf0ffdce6c66a0e95753d8 / IV: 1251c3b85365f9b56a956c10 |
C2 Account Pool (16 accounts)
| Handle | Context |
| typhonian, tartarean, erebean, stygian, orphic | Greek mythology-themed C2 accounts |
| nemean, spartan, basilisk, manticore, styx | Greek mythology-themed C2 accounts |
| aegis, thunderbolt, tempest, cataclysm, onslaught, havoc | Greek mythology-themed C2 accounts |
MITRE ATT&CK Mapping
| Technique | ID | Application |
| Supply Chain Compromise: Software Supply Chain | T1195.002 | Backdoored npm packages published via compromised CI/CD OIDC credentials |
| Command and Scripting Interpreter: JavaScript | T1059.007 | Payload execution via node index.js preinstall hook and Bun runtime |
| Obfuscated Files or Information | T1027 | Four-layer obfuscation: ROT-21, AES-128-GCM, obfuscator.io string table, B5 cipher |
| Unsecured Credentials: Credentials In Files | T1552.001 | Sweep of ~/.aws/credentials, ~/.npmrc, ~/.kube/config, .env files |
| Unsecured Credentials: Credentials in Environment Variables | T1552.007 | Collection of GITHUB_TOKEN, AWS_ACCESS_KEY_ID, cloud credential env vars |
| OS Credential Dumping | T1003 | /proc/{pid}/mem read of Runner.Worker process for masked secret extraction |
| Exfiltration Over C2 Channel | T1041 | AES-256-GCM encrypted HTTPS POST to attacker endpoint |
| Exfiltration to Code Repository | T1567.001 | GitHub Contents API commits as fallback exfiltration channel |
| Event Triggered Execution | T1546 | Claude Code SessionStart hook and VS Code folderOpen task persistence |
| Valid Accounts: Cloud Accounts | T1078.004 | OIDC token abuse for unauthorized npm publish |
Phoenix Security Platform Recommendations
The Miasma campaign demonstrates the zero-CVE detection gap directly. All 96 malicious versions were published using legitimate OIDC-issued npm credentials from what appeared to be the canonical Red Hat CI pipeline. No CVE exists. No advisory was pre-published. Scanner workflows dependent on CVE assignment had no detection surface during the active exposure window.
Phoenix Security’s malware intelligence platform detected frontend-components-config-utilities@4.11.3 and tsc-transform-imports@1.2.4 through behavioral signal analysis — install hook abuse, credential harvesting pattern, payload download, and exfiltration signals — scored and queued for analyst review within minutes of publication.
Reachability analysis identifies which build environments actually executed an affected package’s preinstall hook versus environments that listed the package as a dependency but installed from a cached or pre-publication state. This separates confirmed-executed exposure from theoretical dependency graph exposure — a material difference when scoping credential rotation.
Remediation campaigns track the multi-step response across affected engineering teams: lockfile updates per repository, credential rotation completion per environment, persistence artifact cleanup per developer machine, OIDC rebinding confirmation per package, and container image rebuilds per affected registry.
Attack surface management identifies CI pipelines and build environments running the affected @redhat-cloud-services scope, surfacing the full organizational exposure map before any individual team self-reports.
Contextual deduplication consolidates findings across the 32 affected packages into a single tracked incident with shared remediation state, rather than generating 96 separate alerts across teams.
More Coverage. Full Shai-Hulud / TeamPCP lineage coverage including prior waves, IOC cross-reference, and the Phoenix npm compromise scanner: https://phoenix.security/mini-shai-hulud-teampcp-tanstack/ | Scanner: https://github.com/Security-Phoenix-demo/Shai-Hulud-Sha1-Hulud-V2-npm-compromise-scanner
External References
- Aikido Security — Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages (June 1, 2026)
- Socket Security — Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages (June 1, 2026) — Primary source for technical analysis, obfuscation layers, and IOCs
- StepSecurity — Malware in @redhat-cloud-services npm Packages: Runtime Analysis (June 1, 2026) — Primary source for Harden-Runner runtime trace, worm propagation, and obfuscation breakdown
- StepSecurity disclosure — RedHatInsights/javascript-clients Issue #492
- StepSecurity disclosure — RedHatInsights/frontend-components Issue #2329
- StepSecurity disclosure — RedHatInsights/platform-frontend-ai-toolkit Issue #57
- Phoenix Security — Mini Shai-Hulud / TeamPCP: TanStack and Mistral Campaign
- Phoenix Security Malware Intelligence Platform — https://phxintel.security/malware.html
- Phoenix Security Shai-Hulud npm Scanner — https://github.com/Security-Phoenix-demo/Shai-Hulud-Sha1-Hulud-V2-npm-compromise-scanner
- Socket Security — Red Hat Cloud Services Package Compromise campaign tracker
- npm Registry — @redhat-cloud-services scope version history