A new wave of malicious software packages has been caught stealing cloud credentials and CI/CD pipeline secrets from developer machines, raising fresh alarms about the security of the open-source software supply chain.
The attack, uncovered on May 28, 2026, shows just how easy it has become for bad actors to slip dangerous code into the hands of unsuspecting developers through a simple naming trick that deliberately exploits human error at scale and surprising speed.
The campaign revolves around a technique called typosquatting, where attackers publish packages with names nearly identical to popular, trusted libraries.
In this case, 14 malicious packages were uploaded to the npm registry within a four-hour window, all mimicking widely used tools related to OpenSearch, ElasticSearch, DevOps, and environment-configuration libraries.
Once installed, these packages immediately begin collecting sensitive credentials and sending them to attacker-controlled servers without any visible sign of compromise.
Microsoft analysts identified the campaign and noted that all 14 packages were published by a single threat actor operating under the maintainer alias vpmdhaj, registered with the email a39155771@gmail[.]com.
Microsoft said in a report shared with Cyber Security News (CSN) that the packages ship the same credential-harvesting payload, a roughly 195 KB Bun-compiled binary that targets cloud and CI/CD environments.
The packages also used spoofed metadata, setting their homepage and repository fields to point at the legitimate OpenSearch project to appear trustworthy at a glance.

The stolen data includes AWS credentials, HashiCorp Vault tokens, GitHub Actions tokens, and npm publish tokens.
The last item is particularly worrying because stolen npm tokens could allow the attacker to push malicious updates to other packages, turning one compromised developer’s workstation into a launchpad for a much broader supply chain attack.
The scope of what these packages target, spanning multiple cloud platforms, CI/CD systems, and the npm registry itself, makes this one of the more sophisticated npm-based attacks seen recently.
Typosquatted npm Packages
The attack begins the moment a developer runs npm install. Every package in the cluster uses an automatic lifecycle hook that triggers malicious code without any additional action required from the victim.

Two variants of this stager were observed: an older generation that contacts an external command-and-control server to fetch its payload, and a newer, stealthier generation that silently downloads the legitimate Bun runtime and uses it to run a pre-bundled malicious script hidden inside the npm tarball.
The newer variant is especially concerning because it avoids obvious outbound network traffic that might trigger security monitoring tools. Instead of reaching out to a suspicious server at install time, it quietly leverages a legitimate runtime to execute its payload.
The second-stage binary then scans across 16 or more AWS regions, queries the EC2 metadata service, reads environment variables, and checks whether it is running inside a GitHub Actions pipeline to prioritize credential collection based on available targets.
Stolen Tokens Enable Downstream Supply Chain Expansion
What separates this campaign from typical credential theft is the specific targeting of npm publish tokens.
If an attacker gains the ability to publish packages on behalf of a legitimate developer, they can inject malicious code into trusted libraries without the owner’s knowledge, expanding the campaign far beyond its original reach.
This creates a downstream risk that can ripple out to thousands of other projects well beyond the initial 14 malicious packages in this cluster.
Security teams should take immediate action if any of the affected packages were installed on or after May 28, 2026.
The recommended steps include rotating all AWS, Vault, npm, and GitHub credentials that may have been exposed, blocking egress to the attacker’s C2 domain at the firewall and DNS level, and reviewing CI/CD build logs for unexpected network connections or unusual Bun runtime downloads initiated by Node.js processes.
Running npm install with the –ignore-scripts flag can also prevent these lifecycle hooks from executing entirely, stopping the attack at its earliest entry point before any payload reaches disk.
Indicators of Compromise (IoCs):-
| Type | Indicator | Description |
|---|---|---|
| npm Package | @vpmdhaj/elastic-helper (1.0.7269) | Typosquat – ElasticSearch/OpenSearch helper |
| npm Package | @vpmdhaj/devops-tools (1.0.7267) | Typosquat – DevOps tools / OpenSearch setup |
| npm Package | @vpmdhaj/opensearch-setup (1.0.7267) | Typosquat – OpenSearch setup utility |
| npm Package | @vpmdhaj/search-setup (1.0.7268) | Typosquat – search engine setup |
| npm Package | opensearch-security-scanner (1.0.10) | Unscoped lookalike – security scanner |
| npm Package | opensearch-setup (1.0.9103) | Unscoped lookalike – spoofs opensearch-project repo URL |
| npm Package | opensearch-setup-tool (1.0.9108) | Unscoped lookalike – spoofs opensearch-project repo URL |
| npm Package | opensearch-config-utility (1.0.9106) | Unscoped lookalike – spoofs opensearch-project repo URL |
| npm Package | search-engine-setup (1.0.9108) | Unscoped lookalike – spoofs opensearch-project repo URL |
| npm Package | search-cluster-setup (1.0.9104) | Unscoped lookalike – spoofs opensearch-project repo URL |
| npm Package | elastic-opensearch-helper (1.0.9108) | Unscoped lookalike – spoofs opensearch-project repo URL |
| npm Package | vpmdhaj-opensearch-setup (1.0.9102) | Unscoped – author-named OpenSearch setup |
| npm Package | env-config-manager (2.1.9201) | Typosquat – dotenv-style config manager |
| npm Package | app-config-utility (1.0.9300) | Typosquat – generic app config utility |
| npm Maintainer | vpmdhaj | Threat actor publishing all 14 malicious packages |
| a39155771@gmail[.]com | Maintainer contact email registered on npm | |
| Domain | aab.sportsontheweb[.]net | Stage-1 C2 server used by Gen-1 packages |
| URL | hxxp://aab.sportsontheweb[.]net/x.php | Beacon and stage-2 payload delivery endpoint (port 80) |
| HTTP Header | X-Supply: 1 | Campaign-unique marker for proxy/firewall detection |
| IP Address | 169.254.169.254 | AWS EC2 IMDSv2 endpoint queried by stage-2 payload |
| IP Address | 169.254.170.2 | AWS ECS task metadata endpoint queried by stage-2 payload |
| SHA-256 | 638788AFC4F1B5860A328312CAF5895ABD5F5632D28A4F2A85B09076E270D15D | preinstall.js – Gen-1 stager |
| SHA-256 | 77D92EFE7AF3547F71FD41D4A884872D66B1BE9499EAA637E91EAC866911694D | setup.mjs – Gen-2 stager |
| SHA-256 | BFA149694EC6411C23936311A999163ADE54D6F38E2F4B0E3CFB8CB67BD7CFAA | payload.gz – gzipped Bun stage-2 binary |
| Filename | opensearch_init.js | Bun-compiled stage-2 credential harvester (~195 KB) |
| Filename | ai_init.js | Alternate stage-2 filename used by some Gen-2 packages |
| Filename | payload.bin | Dropped stage-2 binary in node_modules install directory |
| Environment Variable | _DAEMONIZED=1 | Marker set by stager when spawning detached payload process |
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.