# vpmdhaj OpenSearch / ElasticSearch / DevOps typosquat burst (14 npm packages, Bun stager → cloud + CI/CD secret theft)

> Microsoft Threat Intelligence flagged 14 typosquat npm packages published on 2026-05-28 by a single new maintainer alias `vpmdhaj` (`a39155771@gmail.com`) in a ~4-hour window. Install-time stager pulls a ~195KB Bun-compiled credential harvester from `aab.sportsontheweb[.]net/x.php` (`X-Supply: 1` header) and exfiltrates AWS, HashiCorp Vault, GitHub Actions and npm publish tokens.

- Published: 2026-05-28
- Severity: high
- Kind: Typosquat - A package that never had a legitimate version, named to be mistaken for a real one - a misspelling, a lookalike scope, or an impersonated vendor SDK.
- Ecosystems: npm
- Scope: 14 packages, 41 compromised versions
- Tags: typosquat, credential-theft, ci-cd-compromise, infostealer, obfuscation
- Also known as: vpmdhaj burst, sportsontheweb.net campaign
- Detected by: Microsoft Threat Intelligence
- Incident ID: npm-2026-05-28-vpmdhaj-opensearch-typosquats

## Affected packages (14)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [@vpmdhaj/devops-tools](https://dependencywatch.io/package/npm/@vpmdhaj/devops-tools) | npm | 1.0.7267 |
| [@vpmdhaj/elastic-helper](https://dependencywatch.io/package/npm/@vpmdhaj/elastic-helper) | npm | 1.0.7269 |
| [@vpmdhaj/opensearch-setup](https://dependencywatch.io/package/npm/@vpmdhaj/opensearch-setup) | npm | 1.0.7267 |
| [@vpmdhaj/search-setup](https://dependencywatch.io/package/npm/@vpmdhaj/search-setup) | npm | 1.0.7268 |
| [app-config-utility](https://dependencywatch.io/package/npm/app-config-utility) | npm | 1.0.9200, 1.0.9300 |
| [elastic-opensearch-helper](https://dependencywatch.io/package/npm/elastic-opensearch-helper) | npm | 1.0.7265, 1.0.9103, 1.0.9104, 1.0.9105, 1.0.9106, 1.0.9107, 1.0.9108 |
| [env-config-manager](https://dependencywatch.io/package/npm/env-config-manager) | npm | 2.1.9201 |
| [opensearch-config-utility](https://dependencywatch.io/package/npm/opensearch-config-utility) | npm | 1.0.7265, 1.0.9104, 1.0.9105, 1.0.9106 |
| [opensearch-security-scanner](https://dependencywatch.io/package/npm/opensearch-security-scanner) | npm | 1.0.8, 1.0.9, 1.0.10 |
| [opensearch-setup](https://dependencywatch.io/package/npm/opensearch-setup) | npm | 1.0.9000, 1.0.9100, 1.0.9101, 1.0.9102, 1.0.9103 |
| [opensearch-setup-tool](https://dependencywatch.io/package/npm/opensearch-setup-tool) | npm | 1.0.7265, 1.0.9106, 1.0.9107, 1.0.9108 |
| [search-cluster-setup](https://dependencywatch.io/package/npm/search-cluster-setup) | npm | 1.0.7265, 1.0.9102, 1.0.9103, 1.0.9104 |
| [search-engine-setup](https://dependencywatch.io/package/npm/search-engine-setup) | npm | 1.0.7265, 1.0.9105, 1.0.9106, 1.0.9107, 1.0.9108 |
| [vpmdhaj-opensearch-setup](https://dependencywatch.io/package/npm/vpmdhaj-opensearch-setup) | npm | 1.0.9101, 1.0.9102 |

## What happened

Microsoft Threat Intelligence published an analysis on 2026-05-28 of a focused npm typosquat burst by a single newly-created maintainer account `vpmdhaj` (`a39155771@gmail.com`). Within ~4 hours on 2026-05-28 the actor pushed 14 packages - 4 scoped under `@vpmdhaj/*`, 10 unscoped - that impersonate well-known OpenSearch, ElasticSearch, DevOps, and environment-configuration libraries, with several spoofing the upstream `opensearch-project` GitHub URL in their `package.json` to look legitimate to a reviewer skimming metadata.

The scoped tranche (`@vpmdhaj/elastic-helper`, `@vpmdhaj/devops-tools`, `@vpmdhaj/opensearch-setup`, `@vpmdhaj/search-setup`) landed first at versions in the `1.0.7267`–`1.0.7269` range as test releases. The unscoped tranche followed in a ~30-minute burst at `2026-05-28T20:17`–`2026-05-28T21:03` UTC, all stamped with high build numbers (`1.0.9100`–`1.0.9300`, plus `2.1.9201` for `env-config-manager`) so they would outrank legitimate releases in semver resolution. npm unpublished every malicious version listed on 2026-05-29 within hours of detection; the publisher account was suspended.

The payload chain is a two-stage Bun loader. The `postinstall` hook downloads a small JS stager (SHA-256 `638788AFC4F1B5860A328312CAF5895ABD5F5632D28A4F2A85B09076E270D15D`) over HTTP from `aab.sportsontheweb[.]net/x.php` on port 80, carrying the marker header `X-Supply: 1`. The stager pulls a ~195KB Bun-compiled stage-2 (SHA-256 `77D92EFE7AF3547F71FD41D4A884872D66B1BE9499EAA637E91EAC866911694D`), spawns it as a detached process with `__DAEMONIZED=1` so it outlives the npm install, and walks the host for AWS credentials (IMDS, ECS task role, Secrets Manager), HashiCorp Vault tokens, GitHub Actions OIDC and GitHub PATs, and npm publish tokens. The harvester is purpose-built for cloud and CI/CD environments - there is no crypto-wallet logic - which together with the npm-token theft suggests the operator is staging tokens for a downstream worm wave.

- The Bun runtime + cloud/Vault/CI focus mirror the Mini Shai-Hulud TeamPCP family (TanStack 2026-05-11, durabletask 2026-05-19, AntV 2026-05-19), but Microsoft does NOT attribute `vpmdhaj` to TeamPCP - different infrastructure, different stager hash, different aliases, and no worm propagation observed yet in the 24h after publish. Treat the toolchain similarity as a tradecraft signal, not a hard link.
- No GHSA advisories are published yet (as of 2026-05-31 ingest); confirmation comes from Microsoft Defender detections (`Trojan:JS/ObfusNpmJs` family) and direct npm registry verification of the unpublish entries for the 10 unscoped names.
- Scoped `@vpmdhaj/*` versions are sourced from the Microsoft blog; the npm registry returns empty manifests for those names today, consistent with a hard delete rather than an unpublish.
- This burst landed the same day as the `mr.4nd3r50n` / `t-in-one` `oob.moika.tech` dependency-confusion campaign tracked separately in `npm-2026-05-28-moika-dependency-confusion.ts`; the two are unrelated (different infrastructure, different aliases, different payloads) but together demonstrate sustained Russian-language actor activity against npm on 2026-05-28.

## Impact

- AWS credential theft: IMDS, ECS task role, Secrets Manager
- HashiCorp Vault tokens lifted from `~/.vault-token` and `VAULT_TOKEN` env
- GitHub Actions OIDC and `GITHUB_TOKEN` extracted from runner env
- npm publish tokens stolen - primary worm propagation vector for follow-on bursts
- Bun-compiled ~195KB stage-2 payload runs as detached process with `__DAEMONIZED=1` to survive `npm install` exit

## What to do

1. Audit `package.json`, lockfiles and CI caches for the 14 names below; npm has unpublished every malicious version listed but cached copies in CI may persist
2. Block egress to `aab.sportsontheweb[.]net` and hunt for outbound HTTP requests carrying `X-Supply: 1`
3. Rotate any AWS access keys, ECS task role credentials, Vault tokens, GitHub PATs, OIDC trust relationships and npm tokens reachable from a host that installed one of these packages
4. Hunt for `__DAEMONIZED=1` in process env or shell history on developer / CI hosts
5. Add stager and payload SHA-256 hashes to EDR allow-blocklists: `638788AFC4F1B5860A328312CAF5895ABD5F5632D28A4F2A85B09076E270D15D` (stage 1), `77D92EFE7AF3547F71FD41D4A884872D66B1BE9499EAA637E91EAC866911694D` (stage 2)
6. Enforce internal-scope reservation for `@opensearch-project`, `@elastic`, and any internal DevOps scope so confusion typosquats lose semver resolution

## Check your own dependencies

- Check a package-lock.json against this incident: https://dependencywatch.io/check/package-lock-json

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [Typosquatted npm packages used to steal cloud and CI/CD secrets](https://www.microsoft.com/en-us/security/blog/2026/05/28/typosquatted-npm-packages-used-steal-cloud-ci-cd-secrets/) - Microsoft Threat Intelligence

---

Canonical page: https://dependencywatch.io/incident/npm-2026-05-28-vpmdhaj-opensearch-typosquats
Markdown version: https://dependencywatch.io/incident/npm-2026-05-28-vpmdhaj-opensearch-typosquats.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
