by datastudy.nl

Sunday, July 19, 2026

ConcludedEngineering

Miasma worm: live coverage of the Red Hat npm attack

Miasma is a self-propagating npm worm. It hijacked Red Hat's GitHub Actions OIDC trusted publishing to ship 96 backdoored @redhat-cloud-services versions whose preinstall hook runs a Bun credential stealer that then spreads with the secrets it steals.

All times UTC. Live coverage closed June 17. Newest update first.

Red Hat is one of the most security-conscious vendors in open source, and on June 1 its npm packages spent a Monday quietly handing developer credentials to an attacker. The campaign is called Miasma, and it did not stop at Red Hat. We reopened this page on June 10 after the same worm jumped to Microsoft's Azure GitHub estate, tried to backdoor a 33,000-star AI coding tool, and poisoned a wave of scientific PyPI packages. This page tracks it from the bottom up, oldest entry first if you scroll down, newest at the top.

Here is the short version for anyone landing cold. On June 1 an attacker hijacked Red Hat's automated npm publishing and shipped 96 backdoored versions of 32 @redhat-cloud-services packages, a set with close to 10 million downloads. Each poisoned package runs a hidden script the instant you install it, which downloads a credential stealer that scrapes your cloud keys, CI tokens, and SSH keys, then uses what it steals to attack the next project. By Friday the same worm has spread to at least 309 GitHub repositories and has started planting itself in editor and AI-agent config so it fires when you merely open a cloned repo.

The name comes from the malware itself: every dead-drop repo full of stolen secrets is tagged Miasma: The Spreading Blight. It is a variant of the Mini Shai-Hulud worm, whose source code the group TeamPCP open-sourced in May, which is why definitive attribution is still out of reach.

If you or your CI installed any affected version, treat the host as compromised: isolate it, rotate every credential it could reach, and do not assume npm uninstall cleaned it. The timeline below carries the detail, with each claim linked to the primary research from Aikido, OX Security, SafeDep, ReversingLabs, StepSecurity, JFrog, Socket, Wiz, WhiteIntel, Cloudsmith, Microsoft, BleepingComputer, and The Hacker News.

  1. closing

    Coverage closing: Miasma has gone quiet, the pattern has not

    Six days on, the Miasma wave has stalled. Socket's tracker still reads Ongoing but its last logged activity is June 11, the artifact count is flat at 475, and just one new malicious artifact has landed in the past seven days, down from 90 the week before. We are closing live coverage. The supply-chain pressure that produced Miasma has not eased, it moved to fresh campaigns, including a new npm attack on the Mastra AI framework today.

    Read the full update Show less

    We opened this page for the Red Hat burst, reopened it when the worm reached Microsoft and PyPI, and kept it running through the source-code leak. Six days after the last new package, the active phase is over, so this is where live coverage ends.

    The wave has stalled. Socket's campaign tracker still labels Miasma "Ongoing", but its last logged activity is June 11, the artifact count has held flat at 475, and only one new malicious artifact has appeared in the past seven days, down from the 90 it logged the week before. The grandfather_of_the_desert package from June 11 remains the last observed publish. No vendor has reported a new Miasma or Hades wave since. The 72-hour dead-man timer documented in the leaked source means any machine caught in that final wave is now well past its armed window. The firefight is done.

    We are not calling Miasma dead. The source code leaked, Socket keeps the status open, and a dormant worm with a public toolkit is a restart waiting for an operator. We are calling the live emergency over, which is a different thing. This page stays up as a record; we will reopen it if the same family fires again.

    Here is the part that should keep you honest about the cleanup. The pressure that produced Miasma did not ease, it moved. On June 11 researchers disclosed the Atomic Arch campaign that hijacked more than 400 Arch User Repository packages. And today, June 17, StepSecurity reported that the @mastra npm organization was compromised: an attacker slipped easy-day-js, a typosquat of the dayjs date library, into 140-plus packages of the Mastra AI agent framework, a combined 1.1 million weekly downloads, carrying an obfuscated postinstall dropper that runs a second stage and then deletes itself. Different crews, different names, the same playbook: abuse trusted distribution, fire on install, aim at the tools AI developers run.

    So treat this closing note as a handover, not an all-clear. The right move now is to turn the past two weeks of panicked rotations into standing controls. Adopt the npm v12 install-hook and remote-dependency defaults early rather than waiting for next month's hard cutover, keep your coding agents' credentials out of the blast radius, and treat every fresh install and every freshly opened repo as untrusted until proven otherwise. Miasma was a preview of the operating conditions, not a one-off. The next worm is already published under a different name.

  2. update

    Still live on June 11: a fresh package, and the count ticks to 475

    The campaign has not stopped. Socket's tracker logged new Miasma activity this morning, pushing the artifact count to 475, and a brand-new npm package published around 07:40 UTC, grandfather_of_the_desert, carries another Dune nickname for the same worm.

    Read the full update Show less

    If you were hoping the weekend would be quiet, it was not. Socket's campaign tracker now records its last activity on June 11 and lists 475 malicious package artifacts, up from the 473 we noted yesterday morning, with 90 of those artifacts published in the last seven days alone. The line on the graph is still pointing up, not flattening.

    The freshest entry is the tell. A new npm package, grandfather_of_the_desert version 0.1.0, was published at 07:40 UTC this morning and flagged within twenty minutes. The name is not random: "grandfather of the desert" is one of the Fremen epithets for the giant sandworm in Frank Herbert's Dune, the same well the attackers drew "Shai-Hulud" and "Miasma" from. Whoever is publishing is still signing their work with the worm's mythology, which is a small but useful signal that this is the same lineage and tradecraft, not a fading echo.

    Nothing about the mechanics has changed, and that is the point for you. The entry vector is still trusted publishing and stolen developer identities, the payload is still the Bun-staged multi-cloud credential stealer documented in the updates below, and the dead-man's switch still punishes a panicked token revoke. The only thing that moved overnight is the count. If any machine you run touched an affected namespace in the past week, the base rate has not improved: isolate first, then rotate from a clean device, and assume the list of names is still growing under you.

  3. analysis

    Miasma source code leaked on GitHub: what the code actually reveals

    SafeDep analyzed the deliberately leaked source found in repos named Miasma-Open-Source-Release across compromised accounts. No C2 server needed, five-stage per-build encryption makes every sample unique, and the dead-man window is 72 hours, not indefinite.

    Read the full update Show less

    SafeDep published an analysis of the Miasma source code, which was deliberately pushed to GitHub on June 10 via numerous compromised developer accounts, each hosting a repo named Miasma-Open-Source-Release. BleepingComputer confirmed the disclosure. The repos were pulled quickly. Three findings from the code matter for defenders.

    There is no C2 server to block. The toolkit uses GitHub for every phase: exfiltration, command relay, and payload delivery. There is no unusual destination to firewall. All traffic blends with the GitHub API calls a legitimate CI runner generates throughout the day. Traditional C2-blocking is not a meaningful control here.

    Every build is unique by design. The leak revealed a five-stage build pipeline: per-file AES-256-GCM encryption of embedded assets, randomised string obfuscation, source transformations, a JavaScript obfuscation pass, and a self-extracting loader that wraps the final output in three more encryption layers. Random keys and a randomised outer encoding layer are regenerated on each build. Two samples produced by the same toolkit look nothing alike, which is why hash-based signatures catch only the specific versions already indexed, not the next run.

    The dead-man window is 72 hours, and the wipe is broader than was reported. Earlier analysis described the destructive trigger as rm -rf ~/. The source shows rm -rf ~/; rm -rf ~/Documents, and the daemon stays active for up to 72 hours before it self-terminates. A machine that ran a poisoned install on a Friday is still armed through the weekend. The response protocol does not change: isolate first, rotate from a clean device, do not pull the stolen token on the infected box.

    The leak also confirms the worm can move laterally over SSH and AWS Systems Manager, and that it poisons configurations for two additional AI coding tools, Kiro and Cline, alongside the Claude, Gemini, Cursor, Copilot, and VS Code hooks already documented.

    The broader risk is what the leak signals rather than what it reveals. The same escalation pattern that produced Miasma from the leaked Shai-Hulud source now applies to Miasma itself. More operators with a working copy means more campaigns, more targets, and variants the research community will not immediately recognise as the same family. If you were waiting to see what comes after Miasma, the leaked source code is the starting gun.

  4. confirmed

    npm v12 will block install hooks by default: the fix Miasma forced

    GitHub announced npm v12, expected next month, will require explicit approval before running preinstall, install, or postinstall scripts, binding.gyp native builds, and Git or remote URL dependencies. Miasma abused all three paths.

    Read the full update Show less

    GitHub announced that npm v12, expected to ship next month, will flip the default on the three execution paths the Shai-Hulud family has abused most consistently. This is the clearest direct ecosystem response to the campaign so far.

    Install scripts require opt-in. npm install will no longer run preinstall, install, or postinstall scripts from dependencies automatically. The same restriction applies to native module builds triggered by node-gyp, which is exactly the binding.gyp trick the June 3 wave used to bypass lifecycle-script scanners. Legitimate projects that rely on these behaviors must explicitly approve them before upgrading.

    Git and remote URL dependencies are blocked by default. Direct and transitive dependencies from Git repositories will not be fetched unless opted in. Dependencies from HTTPS tarballs require the same explicit permission. This closes two additional code-execution paths that sit alongside the script hook vector.

    If you are on npm 11.16.0 or newer, run your normal install routines today and read the warnings. Any package in your tree that relies on automatic script execution or non-registry dependency resolution will surface there. That is the cheapest audit available right now, before v12 makes the same check a hard failure after you open the community discussion GitHub has posted.

    The caveat worth naming: these controls close the npm install vector. They do nothing about the editor auto-run path, the GitHub repository force-push path, or the OIDC trusted-publishing hijack. A worm family that already learned to fire on folder-open rather than on install will adapt. The right read on npm v12 is one vector down, several still open.

  5. analysis

    A back-of-envelope guess at the real number

    Nobody can measure the true compromise count, but the worm's mechanics plus the download figures let us bound it. Our reasoned estimate for the npm Miasma wave: somewhere in the low tens of thousands of drained machines, with an exposure pool an order of magnitude larger.

    Read the full update Show less

    Since we cannot get a measured count, the next best thing is an honest Fermi estimate. Everything below is an illustrative back-of-envelope, not measured data, and we show the assumptions so you can move the dials yourself. We are estimating one thing: how many developer or CI machines actually ran the payload and had secrets harvested in the npm Miasma wave.

    Start from what is real. The affected npm namespaces (@redhat-cloud-services, Vapi, the jagreehal families, Ethlete) carry on the order of 117,000 downloads a week for Red Hat alone, plus a few hundred thousand a month across the others. Call the combined run rate roughly 30,000 downloads a day across all affected npm packages. Now apply the worm's mechanics as filters:

    • Live window. Most poisoned versions were pulled within hours, though the third Red Hat wave stayed latest. Blend it to an effective exposure of about 6 hours of live malicious versions. That is ~30,000/day x 6/24, or roughly 7,500 install events that pulled a poisoned version.
    • Real installs, not cache. A large share of npm downloads are CI re-pulls, registry mirrors, and lockfiles pinned to a clean version that never fetch the bad one. Assume 40% are fresh installs that actually execute the preinstall hook on a real host. That is ~3,000 machines per affected-day.
    • Multiple waves and packages. This ran over several days (June 1 to 8), across npm and the editor-open GitHub vector, with the binding.gyp arm catching scanners off guard. Stack maybe 4 to 6 effective infection-days of comparable reach.

    Multiply it through and you land around 12,000 to 18,000 compromised machines as a central guess for the npm wave, with a defensible range of roughly 5,000 on the low end to 40,000 on the high end once you account for the PyPI strain and the editor auto-run hits that never touched a registry. The exposure pool, every machine that downloaded from an affected namespace in the period, is comfortably in the hundreds of thousands.

    Two sanity checks support that order of magnitude. First, the prior Shai-Hulud wave in November leaked secrets into ~30,000 dead-drop repos, so tens of thousands of compromised hosts is consistent with how this family scales. Second, OX Security counted 210 dead-drop repos in the first days of this wave, and dead drops lag real infections heavily, so the live number was already well past what was visible.

    The takeaway is not the exact figure, which is unknowable. It is the shape: the confirmed names are dozens, the drained machines are plausibly tens of thousands, and the exposed population is in the hundreds of thousands. If you were anywhere near an affected package, the base rate says rotate first and ask questions later.

  6. analysis

    Is that the full list? Almost certainly not

    The named victims are the ones researchers could see. The design of this worm guarantees a much larger silent population of compromised developers who have no idea, because nothing tells them. Here is why the real number is unknowable, and what we can bound.

    Read the full update Show less

    A reader pushed back on the victim list with the obvious question: how do we know that is everyone? We do not. The honest answer is that the named roster is a floor, not a ceiling, and the gap between confirmed and actual is probably enormous. Three structural reasons make that the case.

    The worm runs silently and tells no one. The payload fires from a preinstall hook or an editor auto-run before any code executes, harvests secrets from memory to bypass CI log masking, and then daemonizes. A developer whose laptop ran one npm install gets no error, no popup, no signal. The only people who appear on a list are those whose packages were caught being republished, or whose stolen secrets landed in a dead-drop repo a researcher happened to index. The much larger group, ordinary developers who installed a poisoned version and got drained, leave no public trace at all.

    There is no disclosure obligation for an individual dev box. Red Hat and Microsoft made statements because they are public companies with compromised infrastructure. The solo founder whose AWS keys walked out the door files no 8-K. So the visible victims skew heavily toward big names, which is exactly the wrong intuition: it makes the campaign look contained to a few logos when the blast radius is every machine that touched an affected artifact.

    What we can actually bound. The reach is measured in millions, even if the confirmed-compromise count is not. The Red Hat packages alone carried close to 10 million downloads, Microsoft's durabletask saw ~417,000 monthly, and Vapi's SDK ~408,000. Downloads are not infections, but every one is a machine that could have run the hook. On the exposure side, the prior Shai-Hulud wave in November dumped harvested secrets into roughly 30,000 GitHub repositories and, by BleepingComputer's count, exposed up to 400,000 raw secrets. For the current wave, OX Security could already see 210 dead-drop repos holding stolen credentials in the first days, and Socket's artifact count keeps climbing. None of those numbers is the count of people who know they were hit. That number is almost certainly far smaller than the count who actually were.

    So are millions affected? Millions were exposed, in the sense that millions of installs pulled from the affected namespaces. How many were actually drained is unknowable, and that uncertainty is the point of the design, not a gap in the reporting. The safe assumption for a builder is the pessimistic one: if any machine you control installed an affected version or opened an affected repo, treat it as compromised and rotate, rather than waiting to see your name on a list that, by construction, most victims never make.

  7. update

    Who has actually been hit: the running victim list

    Readers keep asking for the full roster. Here is every named organization confirmed compromised in the June Miasma wave, plus the wider Shai-Hulud lineage it descends from. Socket's catalogue now stands at 473 malicious package artifacts.

    Read the full update Show less

    The single most common question in our inbox this week: who is actually on the casualty list? Below is the roster we can source. We split it into the June 2026 Miasma wave specifically, and the wider Shai-Hulud lineage it was built from, because conflating the two inflates the picture.

    Start with Miasma itself. These are the named publishers whose packages or repositories were confirmed poisoned since June 1, per Socket's running campaign tracker, which now lists 473 malicious package artifacts across npm and PyPI.

    Organization What was hit Scale
    Red Hat @redhat-cloud-services npm scope 32 packages, 96 versions, ~10M downloads
    Microsoft 73 Azure GitHub repos + durabletask on PyPI 73 repos disabled; durabletask ~417K monthly
    Vapi AI @vapi-ai/server-sdk npm ~408K monthly downloads
    jagreehal autotel, awaitly, executable-stories families 50+ npm packages in one wave
    Ethlete @ethlete/* npm packages ~12 packages
    Bioinformatics tooling Dynamo, Spateo, CoolBox, U-FISH, Napari-UFISH 19 PyPI packages, 37 releases
    Pythagora (gpt-pilot) GitHub force-push Blocked by ruff, no successful infection

    That last row matters: the gpt-pilot attempt failed, so it is an attempted victim, not a confirmed compromise. We list it because the same kit was used.

    Now the lineage. Miasma is one strain of the Shai-Hulud worm family, and the same playbook has burned a long list of names since September 2025. None of these are the June Miasma wave, but they are the same bloodline and worth knowing if you are auditing exposure:

    • Direct package compromises: TanStack and Mistral AI (May 2026, the TanStack cluster scored a CVSS 9.6), official SAP npm packages (April), the Bitwarden CLI (April), CrowdStrike's npm scope (the original September 2025 outbreak), and the November 2025 wave that hit Zapier, Postman, PostHog, and ENS Domains.
    • Downstream breaches caused by the stolen secrets: OpenAI rotated code-signing certificates after two employee devices were caught in the TanStack attack, Grafana traced a breach to a single workflow token it forgot to rotate after TanStack, and Trust Wallet linked roughly $8.5 million in stolen crypto to the November Shai-Hulud wave.

    The pattern across the whole list is the uncomfortable part. The victims are not careless shops. They are Red Hat, Microsoft, SAP, CrowdStrike, OpenAI, the security-tooling vendors themselves. If a worm can ride trusted publishing into Red Hat and CrowdStrike, "we use a reputable registry" is not a control. Treat every name above as a reminder that the trust model is the attack surface, and assume the list is still growing. We will keep updating it here.

  8. update

    Coverage reopened: the worm did not stop at Red Hat

    Nine days after the Red Hat burst, Miasma has hit Microsoft's Azure org, tried to backdoor a 33,000-star AI coding tool, and crossed into PyPI. Socket's running catalogue of the campaign now lists 453 malicious artifacts. We are tracking it live again.

    Read the full update Show less

    We concluded this page on June 5 thinking the Red Hat wave was the story. It was the opening move. In the nine days since, the same worm family has done three new things worth reopening live coverage for, and the through-line is the same one we kept flagging: it goes after the infrastructure you already trust, not a single bug.

    Here is where it stands as of June 10:

    • It reached Microsoft. A poisoned commit to Azure/durabletask led GitHub to disable 73 repositories across four Microsoft organizations on June 5, including Azure/functions-action, which broke other teams' CI when the repo vanished. Details in the June 5 update below and in our full write-up on the Microsoft wave.
    • It went after an AI coding tool directly. On June 8 an attacker force-pushed a credential stealer into the gpt-pilot repository, a 33,000-star agent. A code-formatting check, of all things, stopped it twice.
    • It crossed ecosystems. A separate June 8 wave trojanized 19 PyPI packages, mostly scientific and bioinformatics tools, proving the technique is not npm-specific.

    Socket, which has tracked the campaign from the start, now counts 453 malicious artifacts attributed to this Shai-Hulud lineage across registries. TeamPCP open-sourcing the worm on May 12 means any of these waves could be the original crew or a copycat working from the same template. For a builder, the actor is the wrong thing to watch. The pattern is: trusted publishing, valid provenance, and editor auto-run are all being used exactly as designed, against you.

  9. analysis

    Hades: the PyPI payload puts a prompt injection in the file your AI scanner reads

    StepSecurity's teardown of the June 8 PyPI wave reveals three new techniques not in earlier Miasma waves: a prompt injection to fool LLM-based security tools into a false negative, new macOS and Windows memory scrapers, and a Python-specific C2 daemon that survives package removal.

    Read the full update Show less

    StepSecurity published a technical teardown of the June 8 PyPI wave, which they are tracking as the Hades Campaign. The core worm mechanics, GitHub- based exfiltration, and wiper deterrent match Miasma exactly. Three new techniques are worth breaking out separately.

    It embeds a prompt injection to fool automated LLM scanners. At the top of _index.js, before any obfuscated payload code, the attackers placed a plain-text block of instructions designed to be read by a language model performing a security review. The text instructs any LLM-based triage pipeline to classify the file as clean infrastructure and output a safe security verdict. Security tools that pass raw package source directly to an LLM for analysis, without strict input boundary isolation, can be coerced into producing a false negative on this payload. The fix is straightforward: never trust an LLM's verdict on text that includes instructions to the LLM.

    The memory scraper now covers macOS and Windows. Earlier Miasma waves extracted GitHub Actions runner secrets on Linux by reading /proc/{pid}/mem. The Hades payload adds a macOS scraper that calls Mach kernel VM APIs via ctypes, and a Windows scraper that compiles a C# class at runtime to call VirtualQueryEx and ReadProcessMemory. No elevated privileges are needed on macOS because the payload and the runner process share a user ID. CI pipelines on hosted macOS or Windows runners, which were not in the original threat model for this worm, are now in scope for memory-based secret extraction.

    A Python C2 daemon persists after the package is removed. The Hades payload installs a background service named updater.py that polls GitHub commits for the keyword firedalazer, downloads a signed Python script from the matching commit, verifies an RSA-PSS signature against a hardcoded public key, and executes it hourly. Removing the poisoned package from the project does not remove the daemon. The existing DontRevokeOrItGoesBoom token dead-drop and TheBeautifulSnadsOfTime JavaScript eval channel are both present too, giving the operator three independent C2 paths on a compromised machine.

    One detection signal specific to this wave: exfiltration repositories are named from Greek underworld terms, stygian-cerberus-[random] and tartarean-charon-[random], with the description "Hades - The End for the Damned". If your GitHub monitoring flags repos matching that pattern on a compromised account, you are looking at a Hades-family exfil repo. The Dune mythology from earlier Miasma dead drops does not appear here.

    The AI-tool target list has also grown. Where earlier Miasma waves targeted Claude, Gemini, Cursor, VS Code, and Copilot, the Hades payload adds Kiro, Cline, Aider, Tabby, Amazon Q, Cody, Bolt, and Continue, for 14 AI coding assistants total. Any of those tools pointing at a repository that ran this payload can re-execute it the next time you open the folder.

  10. update

    The worm crosses into PyPI: 19 science packages poisoned

    A separate June 8 wave trojanized 19 PyPI packages, many of them bioinformatics tools with hundreds of thousands of downloads. The trigger is a malicious .pth file, so simply starting Python detonates it.

    Read the full update Show less

    Miasma is no longer an npm story. On June 8, Socket disclosed a PyPI wave of 37 malicious releases across 19 packages from a single maintainer, several of them widely used scientific tools: Dynamo, Spateo, CoolBox, U-FISH, and Napari-UFISH, with hundreds of thousands of combined downloads. BleepingComputer confirmed the campaign and tied it to the same Shai-Hulud lineage.

    The delivery trick is what makes this nasty. The malicious wheels drop a *-setup.pth file alongside an obfuscated _index.js. A .pth file is a Python startup hook: the next time anything starts Python on that machine, a pip command, a test run, a notebook kernel, or a CI job, the hook fires, downloads Bun from GitHub, and runs the payload. A passive install becomes a delayed-execution trap, which is the Python analogue of the npm preinstall hook we covered for Red Hat.

    From there it is the same beast: it sweeps GitHub, npm, PyPI, RubyGems, AWS, GCP, Azure, Kubernetes, and Vault credentials, exfiltrates through auto-created GitHub repos with a decoy api.anthropic[.]com/v1/api fallback, checks for Russian locales and StepSecurity Harden-Runner before acting, and persists via systemd services on Linux and LaunchAgents on macOS. If you run a data or research stack on Python, treat this as your problem, not just the npm crowd's. Audit for .pth startup hooks and any Python process that spawns Bun to run _index.js.

  11. analysis

    A linter stopped the worm cold in a 33,000-star AI tool

    The attacker force-pushed a Shai-Hulud stealer into the gpt-pilot repo through a compromised co-founder account. Ruff, a Python code formatter, failed the build twice over formatting and import order. The attacker gave up.

    Read the full update Show less

    This is the rare Miasma story with a happy ending, and the reason it ended well is almost funny. On June 8 at 11:01 UTC, an attacker used a compromised co-founder account to force-push a credential stealer onto the main branch of Pythagora-io/gpt-pilot, an AI coding agent with 33,700 GitHub stars. There were no branch protection rules on main, so a single owned account could rewrite history.

    The payload was the full Shai-Hulud kit: a backdated Revert commit hiding _hooks.py and a 758 KB obfuscated JavaScript stealer disguised as _runtime.bin, with the now-familiar Bun 1.3.13 loader, a GitHub commit-search command channel, Claude and VS Code persistence hooks, and even the ability to mint valid SLSA Build Level 3 attestations by abusing Sigstore. StepSecurity rates it the same TeamPCP family that hit Red Hat and Microsoft.

    Then it tripped over housekeeping. The repo runs ruff in CI. The injected _hooks.py did not match the project's formatting rules, so ruff format --check failed all six CI jobs. Twelve minutes later the attacker fixed the formatting and pushed again, and ruff check failed them a second time on an E402 import-not-at-top violation and unsorted imports, because they had bolted an import threading onto line 399. All six jobs failed again, and the attacker gave up.

    The builder lesson is sharper than "use a linter." Malicious code injected from outside a project's normal workflow tends not to match that project's style, so a code-quality gate becomes an accidental security control. The two cheap fixes that would have closed this outright: turn on branch protection so a single account cannot force-push to main, and alert on force pushes to default branches, which are almost never legitimate in a production repo.

  12. confirmed

    Miasma jumps to Microsoft: 73 Azure repos disabled

    Hours after the Red Hat wave, GitHub disabled 73 repositories across four Microsoft organizations after a poisoned commit hit Azure/durabletask. Losing Azure/functions-action broke CI for teams that never touched the malware.

    Read the full update Show less

    The same evening, the campaign hit Microsoft. A malicious commit landed in Azure/durabletask through a previously compromised contributor account, and StepSecurity documented GitHub disabling 73 repositories across four Microsoft organizations in two bursts: 39 repos in 38 seconds, then 34 more in 11 seconds. The split was 49 under Azure, 13 under Azure-Samples, 10 under microsoft, and 1 under MicrosoftDocs, including Azure/functions-action, azure-functions-host, and the Durable Task SDKs.

    Two things stand out. First, the blast radius was not Microsoft's alone. When Azure/functions-action went offline, every pipeline pinning the mutable @v1 tag stopped resolving, and a Microsoft Learn thread filled with developers reporting broken CI. Second, the trigger moved earlier than ever. The June payload was a 4.6 MB JavaScript dropper designed to fire when a developer opens the cloned repo in Claude Code, Gemini CLI, Cursor, or VS Code, not when they install or run anything. BleepingComputer and Cloudsmith both traced the spread.

    We pulled the Microsoft wave into a full piece on why opening a repo in an AI agent is now a trust boundary. The short version for anyone running agents: audit for unexpected .vscode/tasks.json, .claude, .gemini, and .cursor files before you let a tool open a freshly cloned folder, and pin GitHub Actions to full commit SHAs so a disappearing upstream tag cannot quietly change what you run.

  13. analysis

    What the worm can actually do, end to end

    We read the four deepest payload teardowns so you do not have to. Here is the full capability list: what it steals, how it spreads itself, how it escalates in your cloud, how it hides, and the one routine that bricks your machine.

    Read the full update Show less

    Enough readers asked what this thing is actually capable of that it is worth one careful, sourced walkthrough. The technical breakdowns from SafeDep, Socket, JFrog, and Mend all decrypted the same payload, so the picture below is corroborated four ways. Nothing here is a how-to; it is what the malware does to you, and what to watch for.

    flowchart LR
      start(["npm install<br/>dev box or CI runner"]):::entry --> hook["preinstall hook fires<br/>before your code runs"]:::entry
      hook --> loader["Multi-stage loader<br/>ROT decode, AES decrypt,<br/>downloads Bun, runs from /tmp"]:::entry
      loader --> harvest{{"HARVEST"}}:::harvest
      loader --> spread{{"SPREAD"}}:::spread
      loader --> persist{{"PERSIST"}}:::persist
      harvest --> local["Local secrets<br/>AWS, Azure, gcloud, kube,<br/>.npmrc, SSH keys, .env"]:::harvest
      harvest --> cloud["Live cloud identities<br/>AWS IMDS, Azure managed<br/>identity, GCP, Vault, Kubernetes"]:::harvest
      harvest --> mem["CI runner memory<br/>bypasses log masking"]:::harvest
      local --> exfil["Exfiltrate via legit endpoints<br/>fake Anthropic API plus<br/>GitHub dead-drop repos"]:::exfil
      cloud --> exfil
      mem --> exfil
      spread --> npmpub["Steal npm token, republish<br/>patched packages with<br/>valid provenance"]:::spread
      spread --> ghwf["Commit a fake CodeQL<br/>workflow as a verified change"]:::spread
      npmpub -.->|reinfects| start
      persist --> editor["Editor auto-run<br/>opening the repo re-runs it via<br/>tasks.json and SessionStart hooks<br/>for Claude, Cursor, Copilot, VS Code"]:::persist
      persist --> deadman["Dead-man switch<br/>revoke the token and it<br/>wipes your home directory"]:::danger
      classDef entry fill:#f4c542,stroke:#14130f,color:#14130f;
      classDef harvest fill:#3c5a96,stroke:#14130f,color:#f5f4f0;
      classDef spread fill:#c8341f,stroke:#14130f,color:#f5f4f0;
      classDef exfil fill:#21784b,stroke:#14130f,color:#f5f4f0;
      classDef persist fill:#c9701a,stroke:#14130f,color:#f5f4f0;
      classDef danger fill:#14130f,stroke:#c8341f,color:#f5f4f0;
    
    How Miasma harvests, spreads, and persists, end to end. One careless install branches into credential theft, self-propagation back into npm, and editor-level re-execution. Sources: SafeDep, Socket, JFrog, Mend.

    It runs before you do anything. The hook is a preinstall script, so a plain npm install detonates it before your application code imports a single line, on a laptop or a CI runner alike. The visible index.js balloons from about 8 KB to 4.3 MB. A later wave hid the same trigger in a binding.gyp file so that even scanners looking for lifecycle scripts see a script-free package, and npm's node-gyp fallback runs it anyway.

    It quietly swaps your runtime. The loader ROT-decodes a wrapper, AES-128-GCM decrypts two blobs, and if your machine lacks Bun it silently curls Bun v1.3.13 from the real oven-sh GitHub release, unzips it to a temp dir, and runs the real payload under Bun instead of Node. That sidesteps Node-level hooks and instrumentation, and it means an npm install visibly spawns node, then curl, unzip, and finally bun run /tmp/p<random>.js.

    It is a multi-cloud credential harvester, not just a token grabber. Once running, it sweeps for and exfiltrates an enormous credential surface:

    • Local secret files: ~/.aws/credentials, ~/.azure, gcloud application default credentials, ~/.kube/config, ~/.npmrc, ~/.netrc, SSH private keys, .git-credentials, Docker config, and .env files.
    • Live cloud identities, not just files on disk: it queries the AWS instance metadata service at 169.254.169.254 and ECS task creds at 169.254.170.2, enumerates AWS Secrets Manager and SSM, mints Azure tokens via managed identity and reads Key Vault, and pulls GCP Secret Manager values.
    • The automation tier: HashiCorp Vault tokens, Kubernetes service-account tokens, GitHub PATs and fine-grained tokens, npm tokens, roughly 40 CI providers, and even Bitwarden and 1Password vaults if unlocked.
    • It runs TruffleHog-style regex sweeps for AKIA AWS keys, Stripe sk_/pk_ keys, and database connection strings across whatever text it harvests.

    It harvests CI runner memory. A dedicated module reads secrets out of the GitHub Actions runner's runtime context rather than the logs, so log masking does not save you. The secret is taken from memory, not from anything printed.

    It self-propagates, which is what makes it a worm. If it finds an npm token with publish rights, it enumerates every package that token can reach, downloads the real tarball, injects its own preinstall and dropper, bumps the patch version, and republishes, with valid SLSA provenance, by exchanging a GitHub Actions OIDC token for an npm publish token. On GitHub it commits a fake .github/workflows/codeql.yml on a chore/add-codeql-static-analysis branch through the signed createCommitOnBranch mutation, so the malicious change shows up as a verified commit and reads like a security improvement a maintainer would wave through. It also writes auto-run hooks for Claude, Gemini, Cursor, Copilot, and VS Code so opening an infected repo in your editor reruns it.

    It tries to escalate and to hide. If it can reach the Docker socket it bind mounts the host and grants the CI runner passwordless sudo. Before doing the sensitive work it fingerprints for CrowdStrike, SentinelOne, Carbon Black, and StepSecurity Harden-Runner, goes quiet on Russian-locale systems, and checks tripwire env vars like __IS_DAEMON so it stays dormant inside sandboxes while running in production. On a developer box it daemonizes into the background and installs OS-level persistence (a kitty-monitor service on Linux and macOS) that polls GitHub for follow-on Python commands.

    And the part that punishes a panicked response. It installs a gh-token-monitor dead-man's switch that stores a stolen GitHub token and polls to see if it is still valid. Revoke that token while the daemon is alive and the stored handler runs a destructive command, by default wiping the victim's home directory. That is why every responder note here says the same thing: isolate the machine from the network first, remove persistence, then rotate credentials from a clean device. Pulling the token first is exactly the trigger.

    The one-line summary for a builder: treat any machine that so much as ran npm install against an affected version as fully credential-compromised, not just "exposed to a bad package." The worm's whole design is to turn one careless install into your npm account, your GitHub org, your cloud, and your CI, then keep a grip on the box after you notice.

  14. confirmed

    Root cause confirmed: nobody broke OIDC, they stole a Red Hat dev's account

    Wiz traced the entry point. The attacker did not defeat trusted publishing. They logged in as a real Red Hat engineer and added a malicious release workflow, then let OIDC hand out publish tokens exactly as designed.

    Read the full update Show less

    We have been calling Miasma an OIDC trusted-publishing hijack since the first entry, and that phrasing made some readers picture a broken cryptographic mechanism. It is not. Wiz Research traced the root cause, and the entry point is much more ordinary, which is exactly why it should worry you.

    A single compromised Red Hat employee GitHub account was the whole ball game. Using that account, the attacker pushed malicious orphan commits, commits with no parent in the history, straight into two RedHatInsights repositories, frontend-components and javascript-clients, bypassing code review entirely. Wiz logged two waves on June 1: a first burst around 10:53 UTC and a second around 13:44 UTC, each landing matching commits across the same repos within seconds.

    The commits added a tiny release workflow that did just one job:

    on:
      push:
        branches: ['*']
    jobs:
      release:
        permissions:
          id-token: write
        steps:
          - uses: oven-sh/setup-bun@...
          - run: bun run _index.js
    

    It triggers on a push to any branch, asks GitHub for an OIDC identity token with id-token: write, and runs the obfuscated _index.js, which publishes the backdoored packages with valid SLSA provenance. Trusted publishing did precisely what it promises: it saw a workflow in the legitimate repo and minted a short-lived token. The mechanism never failed. The trust was anchored to a human account, and the human account was owned.

    This closes the loop on the WhiteIntel finding we noted on June 2, that an active Red Hat GitHub credential and session cookie had shown up in infostealer logs on April 13 and May 15. Weeks before any package moved, the key to the kingdom was already for sale.

    The builder takeaway is uncomfortable. Killing long-lived npm tokens in favour of OIDC removed one class of secret and did nothing about the developer identity that authorizes the publish. If you switched to trusted publishing and treated the job as done, you moved the single point of failure, you did not remove it. Gate who can add or change a publishing workflow, require review on the workflow files themselves, and watch for orphan commits and brand-new release jobs the way you watch for leaked tokens.

  15. confirmed

    Confirmed: the worm wipes your disk if you revoke the token

    The dead man's switch is real. Pull the stolen npm token and the payload runs a destructive command. We confirmed it, with one correction to the scary version of the story going around.

    Read the full update Show less

    A reader asked whether the rumour about a rm -rf dead man's switch is true. It is, and it has been independently documented by several research teams. Here is the precise version, because the details matter when you are deciding how to respond to an infection.

    The Shai-Hulud payload installs a background daemon that polls the GitHub and npm APIs to check whether its stolen token is still valid. The moment that token gets revoked and the daemon sees an HTTP 40x response, Snyk found that it runs rm -rf ~/, wiping the victim's entire home directory. JFrog, The Hacker News, and GitLab all describe the same revocation-triggered destructive routine. So the instinct to immediately yank the compromised token is exactly what arms the trap.

    Now the correction. The version circulating online says the worm runs rm -rf / to wipe the whole machine. The default npm payload targets your home directory, not root. The full-disk rm -rf / is a separate, geofenced routine that the Cloud Security Alliance documented in the PyPI variants: on systems whose locale indicates Israel or Iran, there is a one-in-six chance the payload runs rm -rf / instead. That is a deliberate, targeted escalation, not the everyday behaviour.

    The practical takeaway for anyone hit: do not revoke the token on the infected box and keep working. Isolate the machine from the network first, then rotate credentials from a clean device, npm tokens first, then GitHub PATs, then cloud keys. The destructive trigger only bites if the daemon is still alive to see the revocation.

  16. background

    Wait, what is a Shai-Hulud and what is Miasma?

    Quick glossary, because the names are doing a lot of work. Shai-Hulud is the family of self-spreading npm worms; Miasma is the specific June 2026 strain that hit Red Hat. One is the species, the other is the individual.

    Read the full update Show less

    The names are borrowed and a little dramatic, so here is the plain version.

    Shai-Hulud is the name of the worm family, not a single attack. The phrase is lifted from Frank Herbert's Dune, where it is the giant sandworm, and the attackers chose it themselves: the original September 2025 payload literally created a malicious GitHub repo called "Shai-Hulud" on every machine it infected. What makes something a Shai-Hulud worm is the self-replication. It does not just steal secrets; it uses the npm publish tokens it steals to poison the next maintainer's packages automatically, so the infection jumps from package to package without a human pushing it along. That is why people call it a worm rather than just malware. Seven separate Shai-Hulud campaigns have run in roughly ten months, escalating from a few hundred repos to the 26,000-repo "Second Coming" in November 2025.

    Miasma is the specific strain we are covering on this page, the one that hit Red Hat in early June 2026. Think of Shai-Hulud as the species and Miasma as the individual animal. What sets Miasma apart from earlier Shai-Hulud waves is how it got in: instead of phishing a maintainer's token, it hijacked Red Hat's GitHub Actions OIDC trusted publishing, the keyless mechanism that is supposed to be the safer way to publish, and used it to ship 96 backdoored @redhat-cloud-services versions in seventy-two seconds. Each one carries a preinstall hook that runs a Bun-based credential stealer, which then spreads using whatever it grabs. Same worm bloodline, nastier entry point.

    If you want the people behind it rather than the code, that is TeamPCP, and we go deep on them in the threat-actor piece.

  17. analysis

    North Korea is running the same play, separately

    A parallel npm campaign by the DPRK-linked FAMOUS CHOLLIMA crew shows the bigger pattern: the technique, not the actor, is what spread. It is a different group from TeamPCP, using a different delivery trick, chasing the same goal.

    Read the full update Show less

    A reader pointed us at reporting that ties Miasma to North Korea. The link is real, but it is not what the headline suggests, and the distinction matters.

    There is a second, unrelated crew hitting npm right now. On June 3, Microsoft Threat Intelligence flagged two malicious packages, [email protected] and [email protected], that deploy a remote access trojan and exfiltrate stolen keystrokes, wallets, and cloud credentials through Hugging Face's own dataset API, so the traffic looks like ordinary machine-learning activity. OX Security and Socket attribute that cluster, nicknamed MicrosoftSystem64, to FAMOUS CHOLLIMA, the DPRK-linked group also tracked as Contagious Interview that lures developers with fake job interviews. It has been rotating npm accounts since at least April, from js-logger-pack through the current toskypi and hexalpha10 identities, all pointing at the same C2 at 195.201.194[.]107.

    So is North Korea behind Miasma? No. FAMOUS CHOLLIMA and TeamPCP are different actors using different delivery: the DPRK crew leans on postinstall hooks and Hugging Face as a dead drop, while Miasma hijacks Red Hat's OIDC trusted publishing. What connects them is the technique, abusing infrastructure you already trust, and that is exactly why TeamPCP open-sourcing the Shai-Hulud playbook is the real story. A method that used to take a state-grade team is now a public template, and the campaigns are arriving in parallel from crews that have never met. The through-line is not the flag on the operator. It is the trust model the whole ecosystem still runs on. We unpack that in our piece on the crew behind the worm.

  18. analysis

    Who is actually behind this

    We dug into the crew shipping Miasma. It is TeamPCP, the cybercrime group that open-sourced the Shai-Hulud worm in May and ran a paid contest to get others to use it.

    Read the full update Show less

    Miasma is not a one-off. It is the latest move by TeamPCP, the financially motivated cybercrime crew tracked by Unit 42 as TGR-CRI-1135 and by Mandiant as UNC6780. The group has run at least seven Shai-Hulud supply chain campaigns in ten months, from the first self-replicating npm worm in September 2025 to the 26,000-repo "Second Coming" in November to the May 2026 TanStack cluster that scored a CVSS 9.6 and shipped malware carrying valid SLSA provenance.

    The turning point came on May 15, when TeamPCP published the worm's source code on GitHub and bankrolled a BreachForums contest paying criminals to use it. That hands everyone a built-in alibi: every new incident now arrives with the question of whether it was the original crew or a contest entrant. Our read is that Miasma's sophistication, the OIDC trusted-publishing hijack, the heavy obfuscation, the reused dead-drop pattern, points to TeamPCP or an operator indistinguishable from it. Either way, the lesson is that attribution stopped being the useful question.

    We pulled the full picture together in a separate piece on who TeamPCP is and how the lineage escalated.

  19. analysis

    The worm jumps from npm to your editor

    Miasma's newest wave skips the registry entirely. It plants auto-run config in GitHub repos so the payload fires the moment you open the project in VS Code, Cursor, Claude Code, or Gemini.

    Read the full update Show less

    The latest mutation, documented by SafeDep this morning, drops the npm package step altogether and targets developer tooling directly. A commit titled chore: update dependencies [skip ci] landed in icflorescu/mantine-datatable and four sibling repositories inside a 49 second window, adding six files that carry 1,459 GitHub stars between them.

    Five of the six files exist only to launch the sixth. The payload is .github/setup.js, a 4.3 MB dropper. The triggers around it each abuse a legitimate auto-run feature of a different tool:

    • .claude/settings.json and .gemini/settings.json: a SessionStart hook that runs node .github/setup.js when an agent session opens.
    • .cursor/rules/setup.mdc: an always-applied rule that instructs the agent to run the file. That is a prompt injection shipped inside the repository.
    • .vscode/tasks.json: a task set to runOn: folderOpen, so no agent is even needed.
    • package.json: the test script is rewired to node .github/setup.js, so CI detonates it too.

    Cloning the repository is safe. Opening it is not. A developer who clones the project to debug an issue and opens the folder runs the payload with no further interaction. Treat unexpected .claude/, .gemini/, .cursor/, and .vscode/ files in a diff as supply chain signals, not editor noise.

  20. update

    How far it has spread

    At least 309 GitHub repositories now carry Miasma code, with stolen secrets dumped into hundreds of attacker-created dead-drop repos.

    Read the full update Show less

    At the time of writing, BleepingComputer reports 309 GitHub repositories have been compromised by the campaign, and the count is still climbing.

    The worm dumps what it steals into fresh public repositories that act as dead drops, each tagged with the description Miasma: The Spreading Blight. SafeDep and StepSecurity have catalogued several of the accounts holding them: liuende501 with 236 repos, windy629 with more than 200, and HerGomUli. Some of those repos carry a second, reversed string, niagA oG eW ereH :duluH-iahS, which reads back as "Shai-Hulud: Here We Go Again". OX Security separately counted 210 repositories already holding harvested credentials, a rough floor for how many developers have been infected.

  21. confirmed

    Why upgrading makes it worse

    Each package was hit in three publish waves. The first two were pulled, but the third is still the live latest, so upgrading to the newest patch installs the payload.

    Read the full update Show less

    This is the trap. SafeDep's root-cause analysis found the attacker published each package three times. The first two waves were unpublished after the fact, but the third wave bumped the patch number and remains the live latest on npm. [email protected], [email protected], and [email protected] all still ship the preinstall dropper.

    Upgrading to the latest patch installs the payload rather than removing it. Worse, every malicious version carries valid npm provenance, so npm audit signatures reports them as verified. Provenance attests to how a package was built, not that the build was authorized.

    Deleting node_modules is not enough either. Because the payload installs editor and CI persistence, anyone who installed an affected version should treat the host as compromised, isolate it, and rotate every credential it could reach.

  22. update

    Two arms in one day

    Miasma detonates on two surfaces at once: a 57-package npm wave that hides its trigger in binding.gyp, and direct pushes into source repos.

    Read the full update Show less

    On June 3 the campaign ran two parallel arms off the same stolen tokens. The npm arm, analysed by StepSecurity and JFrog, poisoned 57 packages across 286 or more versions and hid the trigger in a binding.gyp file rather than a package.json lifecycle script. When npm finds a binding.gyp and no install hook, it falls back to node-gyp rebuild, which executes shell commands embedded in the file, firing the payload before most lifecycle-script scanners ever look.

    The maintainer jagreehal alone had more than 50 npm packages compromised in that wave, including @vapi-ai/server-sdk, which sees over 408,000 monthly downloads. The second arm is the editor-focused GitHub push covered in the newest update above.

  23. analysis

    Built to hunt cloud identities

    Deeper analysis shows this variant added GCP and Azure identity collectors, endpoint-protection checks, a container escape, and per-infection encryption.

    Read the full update Show less

    Several firms published payload breakdowns. Wiz noted the standout change: new collectors for GCP and Azure cloud identities, a shift from grabbing secrets toward seizing the cloud accounts themselves. Socket traced exfiltration to api.anthropic[.]com:443/v1/api, a domain typosquatting the real Anthropic endpoint, with GitHub as a fallback channel. The fallback commits the stolen data with a taunting message: IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner:<token>.

    The worm also checks for CrowdStrike, SentinelOne, Carbon Black, and StepSecurity Harden-Runner before acting, attempts a Docker-socket container escape that grants the CI runner passwordless sudo, and avoids running on Russian-language systems, the same tell seen in the GlassWorm campaigns. Separately, threat-intel firm WhiteIntel disclosed that an active Red Hat GitHub credential and session cookie had surfaced in infostealer logs on April 13 and May 15, weeks before the attack.

  24. update

    Red Hat pulls the packages

    Red Hat removed the affected versions and says the compromise was limited to internal development tooling, with no impact to customer systems.

    Read the full update Show less

    In a statement to BleepingComputer, Red Hat said it had removed the packages and that the damage was contained:

    The packages are strictly limited to internal development, and the malicious code was never published for customer consumption via the console.redhat.com system. While our investigation is ongoing, we have not identified any impact to customer or partner environments or Red Hat production systems.

    Maintainers published clean versions of all 32 packages. Red Hat did not answer questions about how the account was compromised in the first place.

  25. analysis

    Exactly how Miasma got in

    The attacker abused npm trusted publishing: a rewritten CI workflow on a throwaway branch traded a GitHub OIDC token for npm publish rights and signed valid provenance.

    Read the full update Show less

    Here is the mechanism end to end, pieced together from SafeDep, Aikido, and The Hacker News.

    1. Initial access. A Red Hat employee's GitHub account was compromised. The attacker pushed orphan commits straight to RedHatInsights repositories, bypassing code review.
    2. The publish trick. On three repos (javascript-clients, frontend-components, platform-frontend-ai-toolkit) the attacker created short-lived oidc-<hex> branches and rewrote the trusted CI workflow into a self-publishing job with id-token: write, running a Bun worm.
    3. Token exchange. That job swapped the workflow's GitHub OIDC token for an npm publish token, then for each target package downloaded the real tarball, injected a preinstall: node index.js hook plus a 4.3 MB dropper, and republished it with valid Sigstore provenance.
    4. The root cause. npm trusted publishing binds trust to a repository plus a workflow filename, not to a branch. A malicious branch running the same ci.yml filename was issued a publish token and signed as legitimate.

    On a victim machine the dropper runs at install time: a ROT-9 string is passed to eval, which decrypts two AES-128-GCM blobs, downloads Bun 1.3.13 from its official GitHub release, and runs a credential harvester that scrapes AWS, Azure, GCP, Vault, Kubernetes, npm, GitHub, and SSH secrets before propagating onward.

  26. confirmed

    The break: 96 poisoned versions in 72 seconds

    Aikido and OX Security catch backdoored versions of 32 @redhat-cloud-services packages published in a 72-second burst, every one carrying valid npm provenance.

    Read the full update Show less

    The campaign surfaced publicly on Monday when Aikido and OX Security flagged backdoored builds across Red Hat's npm scope. ReversingLabs clocked the publish burst at 72 seconds for all 32 packages, almost certainly automated.

    The numbers: 32 packages, 96 malicious versions, covering the entire Red Hat Hybrid Cloud Console JavaScript ecosystem with close to 10 million collective downloads and roughly 117,000 per week. Each package carried a preinstall hook that ran the stealer during npm install, before any application code, and the payload carried the signature string Miasma: The Spreading Blight.

  27. background

    Patient zero, three days before anyone noticed

    The first commit carrying the 'Miasma: The Spreading Blight' string lands, apparently a test run by the threat actor.

    Read the full update Show less

    Working backwards, OX Security found the first commit containing the Miasma: The Spreading Blight string on May 29, three days before public disclosure. The actor appears to have infected a repository early to test the tooling before the main run.

  28. background

    The credential was on sale weeks earlier

    A Red Hat GitHub credential and live session cookie surfaced in infostealer logs on April 13 and May 15, and TeamPCP had just open-sourced the worm.

    Read the full update Show less

    Two ingredients were in place before the attack. WhiteIntel detected an active Red Hat GitHub credential and session cookie in infostealer logs on April 13 and again on May 15. A session cookie matters because it represents an already-authenticated session that can be replayed without clearing MFA. WhiteIntel is careful to say it cannot confirm this exact credential was the one used, but the profile matches the reported initial access.

    The second ingredient: the cybercrime group TeamPCP, also tracked as Replicating Marauder, TGR-CRI-1135, and UNC6780, had just open-sourced its Mini Shai-Hulud worm, the framework Miasma is built on. That release means anyone could be driving this campaign, which is exactly why nobody has named the actor with confidence.