14 Typosquatted Packages in 4 Hours. Every One Had Zero Behavioral History.
Microsoft found 14 malicious npm packages impersonating OpenSearch and Elasticsearch. They stole AWS credentials, Vault tokens, and npm publish keys. The legitimate packages score 77–86. The fakes would have scored single digits.
On May 28, a single npm account published 14 packages in four hours. The account was new.
The packages had names like opensearch-setup-tool, elastic-opensearch-helper,
and env-config-manager. Every one of them stole credentials on install.
Microsoft's threat intelligence team published the full analysis. The packages targeted AWS access keys, HashiCorp Vault tokens, GitHub Actions secrets, and npm publish tokens. That last one matters: stolen npm tokens let the attacker pivot into a supply chain attack on whatever the victim maintains.
The packages
| Package | Version | Impersonates |
|---|---|---|
| opensearch-setup | 1.0.9103 | @opensearch-project/opensearch |
| opensearch-setup-tool | 1.0.9108 | @opensearch-project/opensearch |
| opensearch-config-utility | 1.0.9106 | @opensearch-project/opensearch |
| opensearch-security-scanner | 1.0.10 | @opensearch-project/opensearch |
| elastic-opensearch-helper | 1.0.9108 | @elastic/elasticsearch |
| search-engine-setup | 1.0.9108 | @opensearch-project/opensearch |
| search-cluster-setup | 1.0.9104 | @opensearch-project/opensearch |
| env-config-manager | 2.1.9201 | environment config tooling |
| app-config-utility | 1.0.9300 | application config tooling |
| @vpmdhaj/elastic-helper | 1.0.7269 | @elastic/elasticsearch |
| @vpmdhaj/devops-tools | 1.0.7267 | general DevOps tooling |
| @vpmdhaj/opensearch-setup | 1.0.7267 | @opensearch-project/opensearch |
| @vpmdhaj/search-setup | 1.0.7268 | @opensearch-project/opensearch |
| vpmdhaj-opensearch-setup | 1.0.9102 | @opensearch-project/opensearch |
All published by vpmdhaj ([email protected]). All removed from npm within hours.
The attack chain
The first generation used a preinstall hook that called a C2 server
at aab.sportsontheweb.net to download a second-stage binary.
The second generation got cleverer. It skipped the C2 beacon entirely. Instead, it downloaded a legitimate copy of the Bun runtime and used it to execute a pre-bundled 195 KB credential harvester. The harvester:
- Called the AWS EC2 Instance Metadata Service (IMDSv2) and ECS task metadata endpoint
- Ran
sts:GetCallerIdentityandsts:AssumeRolewith a bundled SigV4 signer - Enumerated AWS Secrets Manager across 16+ regions
- Read
VAULT_TOKENandVAULT_AUTH_TOKENfrom the environment - Validated npm tokens via
/-/whoamiand enumerated publish access - Collected GitHub Actions context for targeted follow-up
The npm token theft is the pivot point. One developer runs npm install opensearch-setup-tool,
and the attacker can now publish malicious versions of whatever that developer maintains.
What behavioral signals show
I scored the legitimate packages these fakes were impersonating:
| Package | Score | Publishers | Weekly Downloads | Age | Provenance |
|---|---|---|---|---|---|
| @opensearch-project/opensearch | 77 | 3 | 1.4M | 4.7 years | ✓ |
| @elastic/elasticsearch | 86 | 2 | 2M | 7.5 years | ✓ |
Now consider what the fake packages would have scored:
| Signal | @opensearch-project/opensearch | opensearch-setup-tool |
|---|---|---|
| Age | 4.7 years | 0 days |
| Publishers | 3 | 1 (new account) |
| Weekly downloads | 1.4M | 0 |
| Release history | 35+ releases | 1 release |
| GitHub backing | opensearch-project org | None |
| Provenance | Signed | No |
| Commit score | 77 | < 5 |
Every behavioral dimension diverges. Zero history. Zero downloads. Zero contributors. A score below 5 is not a close call. It's a package that has never earned trust from anyone.
Why this keeps working
Typosquatting isn't new. This attacker didn't invent a novel technique. The packages got removed within hours. Microsoft's detection worked.
But detection after install is damage control. The preinstall hook fires during
npm install. By the time any scanner flags it, your AWS credentials
are already on the attacker's server.
The gap is between installation and detection. Behavioral scoring fills that gap by answering a simpler question: should you trust this package at all?
A package published today from a new account with zero downloads has no behavioral track record.
That's not a heuristic. It's a measurement. And it's available before you run npm install.
The Cursor hook catches this
Since v1.21.0, poc hook installs
a beforeShellExecution hook in Cursor that intercepts package installs.
When your AI coding assistant runs npm install opensearch-setup-tool,
the hook scores the package against the Commit API before the install executes.
A score below 5 triggers a block. The install never runs. The preinstall hook never fires. The credential harvester never touches your AWS keys.
poc hook --global One command. Protects every Cursor project.
Check your project
npx proof-of-commitment Scores every dependency in your lockfile. The packages these typosquats impersonated are legitimate. Your actual risk might be something else entirely — a transitive dependency three levels deep with a single publisher and no provenance.