# Mastra npm Supply Chain Attack: 140+ Packages Backdoored via easy-day-js Typosquat

Attacker compromised @mastra npm org, adding typosquatted easy-day-js with obfuscated postinstall dropper to 140+ packages, exfiltrating credentials via C2.

- Payout: Real-world hack
- Severity: critical
- Program: Mastra
- Analysis by: StepSecurity
- Disclosed: 2026-06-18
- Write-up quality: 7/10
- Original: https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js
- Library page: https://bugbountylibrary.com/r/blog%3Astepsecurity-io-blog-mastra-npm-packages-compromised-using-easy-day-js
- Tags: area:oss domain:oss impact:data-leak impact:mass-exploit kind:incident platform:threat-intel sev:critical tech:ci-cd tech:nodejs technique:recon technique:reverse-engineering vuln:dependency-confusion vuln:secrets-leak

**Target:** npm packages / @mastra organization
**Root cause:** Compromised @mastra org credentials allowed mass republishing of 140+ packages with a dependency on typosquatted easy-day-js pinned as ^1.11.21, which resolved to a malicious 1.11.22 containing an obfuscated postinstall dropper.
**Steps:**
1. Attacker publishes clean easy-day-js@1.11.21 mirroring dayjs metadata
2. Attacker publishes easy-day-js@1.11.22 adding setup.cjs and `"postinstall": "node setup.cjs --no-warnings"`
3. Attacker uses compromised @mastra org creds to republish 140+ packages with `"easy-day-js": "^1.11.21"` dependency
4. Victim runs `npm install @mastra/core`; npm resolves easy-day-js to 1.11.22 and runs postinstall
5. setup.cjs sets `NODE_TLS_REJECT_UNAUTHORIZED=0`, writes `.pkg_history`/`.pkg_logs` beacons, fetches `https://23.254.164.92:8000/update/49890878`, spawns detached stage-2 with C2 `23.254.164.123:443`, self-deletes
**How found:** Researcher observed new easy-day-js versions and @mastra package republishes in tight clusters, inspected tarball for setup.cjs, deobfuscated custom Base64 + rotated string array + XOR marker, and validated runtime behavior in Harden Runner block mode.
**Exploitation:** Postinstall dropper executes at npm install time, disables TLS verification, beacons install path, downloads stage-2 payload from attacker IP, spawns it detached with C2 address, then self-deletes setup.cjs to erase forensics. Stage-2 likely harvests env vars (LLM/cloud/CI credentials) and exfiltrates to C2.
**Escalation:** Caret range ^1.11.21 means future malicious patches auto-resolve without touching @mastra packages; mass org-wide republish scales blast radius to 1.1M+ weekly downloads.
**Insight:** Caret-pinned dependencies on freshly published typosquats are a live attack surface: monitor for new transitive deps whose maintainer differs from the impersonated package's author, and treat any postinstall hook in a date-library clone as hostile.
