A fresh supply-chain wave by the Shai-Hulud/Hades family that infected 20 npm packages in the Leo/RStreams ecosystem, an AWS-native event streaming SDK widely used for Kinesis, Firehose, Lambda and S3-based pipelines.
The malicious releases were detected shortly after publication and, while not a dramatic redesign of prior Hades/Miasma variants, demonstrate the malware family’s continued operational maturity.
The same credential-harvesting and propagation machinery applied to new, high-value targets with updated campaign markers and a small operator-seeding feature.
Leo (RStreams) packages occupy a privileged position in many cloud architectures. Their libraries frequently run on developer workstations, CI/CD runners, and in deployment pipelines where npm install may execute with access to AWS keys, GitHub tokens, npm publish credentials and other application secrets.
JFrog noted roughly 45,000 npm packages downloads across the affected packages in the month before analysis, underscoring the potential reach of any successful compromise. The complete package list and indicators appear in JFrog’s IOC section.
The wave reuses an evasive delivery vector previously documented by JFrog: binding.gyp-based execution. When a package provides binding.gyp without an explicit install script, npm falls back to node-gyp rebuild, and node-gyp evaluates shell expressions embedded in
The malicious packages embed a command such as node index.js inside the binding.gyp sources entry to trigger payload execution during installation while avoiding straightforward checks that only inspect package.json lifecycle scripts.
JFrog Security Research identified a new Shai-Hulud/Hades npm wave affecting 20 packages in the Leo/RStreams ecosystem. This technique preserves stealth and broad compatibility across environments that automatically build native modules.
Once executed, the payload aligns closely with the established Shai-Hulud lineage. Its capabilities include sweeping credential collection from files, environment variables, shell histories, GitHub CLI tokens, cloud credential files, and package-manager tokens.
20 Leo/RStreams npm Packages
The malware implements GitHub “dead-drop” exfiltration by creating repositories under any usable token and committing encrypted result blobs into a results/ directory.
It contains persistence routines for multiple ecosystems npm, PyPI, RubyGems, JFrog/Artifactory and GitHub Actions plus lateral movement helpers (ai_setup.sh, ai_init.js) and a gh-token-monitor dead-man switch.
Notably, the sample retains anthropic-styled camouflage strings such as api.anthropic.com/v1/api, likely intended to mislead casual inspection rather than reflect any third-party compromise.
This wave differs in campaign metadata and a small operational addition. Public markers used by earlier waves (for example, “Miasma – The Spreading Blight” or “Hades – The End for the Damned”) were replaced with the new repository description “Alright Lets See If This Works,” a string JFrog found present in hundreds of public repositories and useful for hunting at the metadata layer.
Token-relay text also changed to “RevokeAndItGoesKaboom.” A gated SEED_PAT path was introduced: the payload checks whether the GITHUB_REPOSITORY contains Seeder before reading SEED_PAT and using it as a sender token.
This appears to be an operator-only or test bootstrap mechanism rather than a broad victim-discovery vector.
Defenders should treat this incident as another reminder that Shai-Hulud payload prioritizes behavior over novelty, repurposing proven code and small indicator changes to circumvent stale detections.
JFrog reports that its customers using Curation immaturity policies were protected within 24 hours through automatic compliance version selection.
Recommended actions include identifying and removing affected versions from projects, lockfiles, CI logs, caches and images; isolating compromised runners; removing persistence hooks and suspicious workflows before rotating credentials; auditing GitHub for unexpected repositories or results/ files; and rotating GitHub, npm, cloud and other credentials only after persistence is eliminated.
IOCs
| Package | Type | Xray ID | Affected version | Last-month downloads |
|---|---|---|---|---|
leo-auth | npm | XRAY-1009715 | 4.0.6 | 1,577 |
leo-aws | npm | XRAY-1009716 | 2.0.4 | 5,160 |
leo-cache | npm | XRAY-1009726 | 1.0.2 | 1,049 |
leo-cdk-lib | npm | XRAY-1009721 | 0.0.2 | 17 |
leo-cli | npm | XRAY-1009724 | 3.0.3 | 321 |
leo-config | npm | XRAY-1009720 | 1.1.1 | 4,967 |
leo-connector-elasticsearch | npm | XRAY-1009713 | 2.0.6 | 2,014 |
leo-connector-mongo | npm | XRAY-1009714 | 3.0.8 | 1,352 |
leo-connector-mysql | npm | XRAY-1009729 | 3.0.3 | 164 |
leo-connector-oracle | npm | XRAY-1009718 | 2.0.1 | 72 |
leo-connector-redshift | npm | XRAY-1009725 | 3.0.6 | 184 |
leo-cron | npm | XRAY-1009723 | 2.0.2 | 238 |
leo-logger | npm | XRAY-1009727 | 1.0.8 | 11,655 |
leo-sdk | npm | XRAY-1009717 | 6.0.19 | 5,530 |
leo-streams | npm | XRAY-1009728 | 2.0.1 | 3,761 |
rstreams-metrics | npm | XRAY-1009731 | 2.0.2 | 1,861 |
rstreams-shard-util | npm | XRAY-1009732 | 1.0.1 | 31 |
serverless-convention | npm | XRAY-1009719 | 2.0.4 | 2,398 |
serverless-leo | npm | XRAY-1009730 | 3.0.14 | 3,625 |
solo-nav | npm | XRAY-1009722 | 1.0.1 | 7 |
Note: IP addresses and domains are intentionally defanged (e.g., [.]) to prevent accidental resolution or hyperlinking. Re-fang only within controlled threat intelligence platforms such as MISP, VirusTotal, or your SIEM.
Follow us on Google News, LinkedIn, and X to Get Instant Updates and Set GBH as a Preferred Source in Google.

