Microsoft Names 'Mini Shai-Hulud' Wave of 14 npm Typosquats Stealing Cloud and CI/CD Secrets

Microsoft Threat Intelligence has named a new npm supply-chain wave the Mini Shai-Hulud campaign. A single maintainer alias, vpmdhaj, published 14 typosquatted packages in four hours that harvest AWS, HashiCorp Vault, npm, and GitHub Actions secrets from CI/CD runners.

Share
Line-art row of near-identical small package boxes on a shelf, each with a tiny lookalike label; a small key icon hangs from one box, and a red dot sits on the key.

Key Takeaways

  • Microsoft Threat Intelligence named a new npm supply-chain wave the Mini Shai-Hulud campaign after a single maintainer alias, vpmdhaj, published 14 typosquatted packages in a four-hour window on May 28, 2026.
  • All 14 packages typosquat OpenSearch, Elasticsearch, DevOps, and environment-configuration libraries and ship a Bun-compiled 195 KB credential harvester that steals AWS, HashiCorp Vault, npm publish, and GitHub Actions tokens from CI/CD runners.
  • Engineering teams should audit npm lockfiles for the 14 packages, rotate every AWS, Vault, npm, and GitHub Actions credential reachable from affected runners, block egress to aab.sportsontheweb[.]net, and run npm install with --ignore-scripts as a default control.

Mini Shai-Hulud is the second npm campaign Microsoft has named in a single 48-hour window — and a reminder that, in 2026, the most efficient path to a company's cloud and CI/CD credentials is still through a typosquatted package on a public registry.

REDMOND, WASHINGTON — On May 28, 2026, Microsoft Threat Intelligence disclosed an active npm supply-chain wave that its researchers named the Mini Shai-Hulud campaign — a single threat actor operating under the newly created maintainer alias vpmdhaj published 14 malicious packages within a four-hour window. The packages typosquat well-known OpenSearch, Elasticsearch, DevOps, and environment-configuration libraries, and several spoof the upstream OpenSearch project's GitHub repository URL inside their package.json to appear legitimate. Once installed, the packages harvest AWS credentials, HashiCorp Vault tokens, GitHub Actions context, and npm publish tokens from the host environment.

The CyberSignal is covering Microsoft's research three days after publication — there is no breaking-news pretense here; the report appeared on May 28 and the packages were removed shortly after. The pairing matters: this is the second npm campaign Microsoft has named in 48 hours, alongside its May 29 disclosure of a separate 33-package dependency-confusion wave. The two operations use different techniques against the same target population of cloud and CI/CD developers.

Disclosure Overview
FieldDetails
DisclosureMicrosoft Threat Intelligence — Microsoft Security Blog, May 28, 2026
Campaign NameMini Shai-Hulud — Microsoft's own designation in the report's metadata; also used in earlier press coverage of related npm waves
TechniqueTyposquatting plus spoofed upstream metadata — not dependency confusion (the technique covered in Microsoft's separate May 29 disclosure)
Packages14 malicious packages published in a four-hour window on May 28, 2026
Maintainervpmdhaj — a newly created npm maintainer alias; contact email a39155771@gmail[.]com
Targeted LibrariesTyposquats of OpenSearch, Elasticsearch, DevOps, and environment-configuration packages — including opensearch-setup, opensearch-setup-tool, search-engine-setup, elastic-opensearch-helper, env-config-manager, app-config-utility
PayloadA Bun-compiled, single-file JavaScript binary of approximately 195 KB — a credential harvester purpose-built for cloud and CI/CD environments
Targets StolenAWS credentials via IMDSv2 and ECS metadata, AWS Secrets Manager material across 16+ regions, HashiCorp Vault tokens, npm publish tokens, GitHub Actions context
Command and Controlaab.sportsontheweb[.]net (Gen-1 stager); Gen-2 stager abuses legitimate Bun runtime downloads from GitHub Releases as a loader
StatusPackages and the vpmdhaj account taken down by npm following Microsoft's report

What Happened

Microsoft's Defender Security Research Team, with Microsoft Threat Intelligence, documented the Mini Shai-Hulud campaign in a May 28 post on the Microsoft Security Blog. The report attributes 14 npm packages to a single maintainer alias, vpmdhaj, all published within a four-hour window on May 28 — a velocity that indicates an automated publishing pipeline. The packages typosquat names from the OpenSearch and Elasticsearch ecosystems and from common DevOps and environment-configuration utilities, including opensearch-setup, opensearch-setup-tool, search-engine-setup, elastic-opensearch-helper, env-config-manager, and app-config-utility. Several unscoped packages set their package.json homepage, repository, and bugs fields to the legitimate github.com/opensearch-project/opensearch-js project, and release versions jump to 1.0.9108 or 2.1.9201 to imply a long, mature history.

Every package declares an install-time hook, so the malicious code executes the moment a victim runs npm install — no require() from the victim's own code is needed. Microsoft documented two stager generations. Gen-1 beacons to an HTTP C2 endpoint at aab.sportsontheweb[.]net with a campaign-unique X-Supply: 1 header, then downloads a gzipped second-stage binary written to disk as payload.bin and spawned detached. Gen-2 eliminates the install-time C2 round-trip entirely: setup.mjs downloads the legitimate Bun runtime from github.com/oven-sh/bun/releases, extracts it, and executes a pre-bundled stage-2 payload that ships inside the npm tarball — abusing a trusted GitHub Releases endpoint as the loader. Both stagers drop the same ~195 KB Bun-compiled credential harvester that queries AWS IMDSv2, calls STS GetCallerIdentity and AssumeRole, enumerates AWS Secrets Manager across 16-plus regions, reads HashiCorp Vault tokens from environment variables, validates npm publish tokens, and collects GitHub Actions runner context.

Typosquatting and Dependency Confusion Are Not the Same Attack

Mini Shai-Hulud and Microsoft's separately disclosed 33-package dependency-confusion campaign landed within 48 hours of each other and target the same defender population, but they are different attacks and the distinction matters operationally. Typosquatting — the technique here — registers package names that mimic real ones, betting that a developer will mistype a dependency or trust a name that looks correct; the defenders' control surface is name vigilance, internal blocklists, and registry-side abuse takedown. Dependency confusion — the technique in the May 29 sibling report — registers names that match a victim's private internal scopes on the public registry, exploiting npm's default of preferring the higher-version public package; the defenders' control surface is private-registry configuration. Both techniques end with malicious code running inside npm install, but the upstream defense for each is different. Mini Shai-Hulud will not be stopped by locking scopes; the 33-package wave will not be stopped by a lookalike blocklist.

The Bun Runtime as a Stealth Loader

The Gen-2 stager is the most operationally novel detail in Microsoft's report. Rather than beacon to a custom C2 host — the noisy behavior that earned Gen-1 its X-Supply: 1 signature — Gen-2 downloads a legitimate, signed release of the Bun JavaScript runtime from github.com/oven-sh/bun/releases for the host's architecture, unpacks it, and runs a pre-compiled stage-2 payload that ships inside the npm tarball. To an outbound proxy, the install-time traffic looks like a Node.js process pulling a popular runtime from GitHub Releases — a request that routinely succeeds and is unlikely to be flagged. Bun's developers are not implicated; the runtime is the lure, not the malware. But the design exploits a defensive blind spot: there is no widely deployed control that distinguishes legitimate runtime fetches from runtime fetches that are about to load a credential harvester. Microsoft's recommended hunt — Bun runtime downloads from GitHub Releases initiated by node.exe — is the closest available proxy.

Mini Shai-Hulud Is a Cluster Name, Not a Worm

The Mini Shai-Hulud designation is cluster naming that emerged from earlier press coverage of related npm waves, and Microsoft has now adopted it in its report's metadata. The label does real cluster-naming work, but it is not a claim that Mini Shai-Hulud is itself the Shai-Hulud worm. The original Shai-Hulud worm The CyberSignal documented when it began generating valid Sigstore provenance badges for its malicious npm packages is self-propagating malware; the copycat operator who pushed Shai-Hulud clones to npm within a week of the source leaking is a separate cluster. Mini Shai-Hulud — as Microsoft has described the May 28 vpmdhaj cluster — is a 14-package typosquat operation, not a worm. The shared name signals lineage and a shared target ecosystem, not a confirmed shared author or codebase.

Scope and Impact

What Mini Shai-Hulud steals is the credential catalog that defines modern cloud development. From AWS, the payload pulls IMDSv2 credentials, ECS task-role credentials, environment-variable credentials, STS session tokens, and Secrets Manager material across 16-plus regions — meaning a single install on a build runner can expose anything stored in Secrets Manager, not only the credentials the runner uses. From HashiCorp Vault, it reads VAULT_TOKEN and VAULT_AUTH_TOKEN. From npm, it validates publish tokens through /-/whoami and enumerates them through /-/npm/v1/tokens, opening the door to downstream pivoting through stolen maintainer tokens. From GitHub Actions runners, it harvests GITHUB_REPOSITORY and RUNNER_OS context. The blast radius is not the 14 packages — it is every cloud account, every Vault, and every downstream npm package the stolen credentials reach.

Mini Shai-Hulud sits inside a broader npm supply-chain pattern The CyberSignal has tracked across May 2026: the developer-trust surface is under sustained pressure from multiple independent operators. In the same fortnight, the Shai-Hulud worm began generating valid Sigstore provenance badges for its malicious packages, a copycat operator pushed Shai-Hulud clones to npm within a week of the source code leaking, the TrapDoor cluster placed AI-assistant-poisoning payloads across npm, PyPI, and Crates, and the Packagist registry confirmed a supply-chain attack that ran a payload from inside package.json itself. The CI/CD layer has been hit in parallel by the Megalodon campaign that backdoored 5,561 GitHub repositories through poisoned workflow files, and the registry itself has begun to respond with staged publishing and 2FA-gated release approval as a structural control. The CyberSignal's most recent quarterly framing — drawn from ESET's APT activity report covering October 2025 through March 2026 — is that 2026 is the year developer-toolchain supply-chain compromise became a primary, not secondary, initial-access path.

Several specifics are not in evidence. Microsoft does not name a threat actor behind the vpmdhaj alias, does not state per-package download counts, and does not say how many organizations executed the payload — the 14-package figure counts what was published, not what was installed. Whether any AWS, Vault, npm, or GitHub Actions credentials were exfiltrated and re-used in follow-on activity is not stated, and downstream pivoting through stolen publish tokens is described as a capability, not an observed outcome. The link between Mini Shai-Hulud and the broader Shai-Hulud worm cluster is a naming convention shared across press coverage and Microsoft's report metadata, not an attribution of shared authorship.

Response and Attribution

For engineering teams, the immediate work is in three layers. First, scope: identify any developer workstation, CI/CD runner, or build container that ran npm install against the 14 affected packages on or after May 28, and pin known-good versions until the audit is complete. Second, hunt: review proxy and DNS logs for any request to aab.sportsontheweb[.]net or carrying the X-Supply: 1 header, and review CI/CD logs for Bun runtime downloads from GitHub Releases by Node.js processes outside documented build steps. Third, rotate: treat as exposed every AWS IAM and STS credential reachable from affected runners, every Secrets Manager entry an affected role could read, every Vault token present on those runners, every npm publish token in the affected maintainer accounts, and every GitHub Actions token that ran on a compromised runner. Cloud-side, hunt CloudTrail for sts:GetCallerIdentity followed by sts:AssumeRole, and for secretsmanager:ListSecrets in cross-region succession from build infrastructure.

The structural control is npm install --ignore-scripts (or npm config set ignore-scripts true globally), with equivalent settings for pnpm and yarn. That single setting would have stopped both stager generations cold, because both rely on the npm lifecycle hook to gain code execution. --ignore-scripts breaks legitimate package installs in some workflows, which is why most organizations do not run with it by default; Mini Shai-Hulud is one more data point that the cost of that breakage is now lower than the cost of leaving lifecycle hooks enabled on every CI/CD runner. Beyond the script flag, the longer-term work is reducing the credential surface a compromised install can reach: short-lived STS sessions with tight IAM scoping, IMDSv2 enforcement with hop-limit hardening, Vault tokens scoped to specific paths and short TTLs, and segmentation between the runner that builds an application and the cloud account that hosts it.

On attribution, Microsoft does not name a threat actor. The vpmdhaj alias is a newly created maintainer identity, and no public reporting links vpmdhaj to TeamPCP, the Shai-Hulud worm authors, or any other named operator. The Mini Shai-Hulud label is cluster naming, not an attribution finding: the campaign sits in the same ecosystem as the rest of the 2026 npm cluster, but a confirmed shared author has not been established. For SOC and threat-hunting teams, the technical indicators — aab.sportsontheweb[.]net, the X-Supply: 1 header, the IMDS and ECS metadata endpoints, the AWS Secrets Manager cross-region enumeration pattern, the __DAEMONIZED=1 environment marker, and Bun-runtime-from-GitHub-Releases downloads by Node.js — translate directly into hunt queries without waiting for attribution to firm up.


The CyberSignal Analysis

Signal 01 — Typosquatting and Dependency Confusion Are Not the Same Problem

Microsoft naming two npm campaigns inside a 48-hour window is more important than the package count in either. Mini Shai-Hulud and the 33-package dependency-confusion wave share an objective — cloud and CI/CD credentials harvested from inside npm install — but they exploit different weaknesses, and the defender controls that stop each are different. Mini Shai-Hulud bets on a developer mistyping or trusting a lookalike name; the 33-package wave bets on a private internal scope leaking onto the public registry. A team that hardens against typosquatting with name blocklists is still exposed to a dependency-confusion hit on an internal scope, and a team that locks private scopes has done nothing about a developer copy-pasting a typosquat into a package.json. The 2026 npm threat model needs both control sets — name vigilance plus scope locking plus --ignore-scripts plus a credential surface that limits the blast radius when one of them fails.

Signal 02 — The Credential Catalog Is the Real Blast Radius

Most coverage will lead with the 14 packages, and the count is genuinely modest. The number that should land is the catalog of credentials the second-stage payload is built to harvest: AWS IMDS credentials, ECS task-role credentials, STS sessions, Secrets Manager material across 16-plus regions, HashiCorp Vault tokens, npm publish tokens, and GitHub Actions runner context. A single install on one build runner exposes not just that runner but every cloud secret an affected IAM role can reach, every Vault path a leaked token can read, and every downstream npm package a stolen publish token can update. The shape of the modern cloud development environment — one runner with broad IAM scope, one Vault token with broad path access, one publish token covering a maintainer's full portfolio — is what gives a 14-package campaign environment-wide consequences.

Signal 03 — A Trusted Runtime Was the Loader This Time

The Gen-2 stager's abuse of Bun is the most defender-relevant detail in Microsoft's report. The campaign does not need a custom C2 fetch during npm install; it pulls a signed, legitimate JavaScript runtime from github.com/oven-sh/bun/releases and uses it to run a pre-bundled payload from inside the npm tarball. To a proxy watching for unusual install-time C2, that traffic is invisible — a Node.js process downloading a popular runtime from GitHub Releases is a request countless legitimate builds make every day. The pattern generalizes: any signed, widely trusted developer tool reachable from inside an npm install hook is a potential loader for the next campaign. The available controls are the ones that work regardless of which trusted runtime an attacker borrows next — disabling npm lifecycle hooks by default, narrowing the credential surface, and treating any runtime fetch from a package install as a hunt-worthy event.


Sources

TypeSource
PrimaryMicrosoft Security Blog — Typosquatted npm packages used to steal cloud and CI/CD secrets (May 28, 2026)
Officialnpm — vpmdhaj maintainer profile (taken down)
ReportingThe Register — 14 malicious npm packages impersonated OpenSearch and Elasticsearch libraries
ReportingOffSeq Threat Radar — Typosquatted npm packages used to steal cloud and CI/CD secrets
AnalysisWiz — Mini Shai-Hulud Strikes Again: TanStack and More npm Packages Compromised
AnalysisSnyk — Mini Shai-Hulud Hits AntV: 300+ Malicious npm Packages Published via Compromised Maintainer Account
BackgroundMicrosoft Security Blog — Malicious npm packages abuse dependency confusion to profile developer environments (May 29, 2026)