If you run npm install for any @mastra/* package in CI, on a build box, or on a dev laptop, treat the host as compromised if it pulled a fresh install after roughly 01:00 UTC on June 17. The @mastra npm scope — the AI-agent framework whose core package alone sees about 918K weekly downloads — was hijacked, and roughly 144 packages were republished with a malicious dependency that executes at install time.
What happened
On 2026-06-17, an attacker used the hijacked npm account ehindero — a former Mastra contributor whose scope access was never revoked — to mass-republish ~144 packages across the @mastra/* namespace in an automated, roughly 88-minute campaign. The packages’ own source was untouched. The malice was a single added production dependency: "easy-day-js": "^1.11.21". Researchers at JFrog, SafeDep, Socket, and StepSecurity converged on the same picture within hours.
The two-stage setup
easy-day-js is a fresh typosquat of dayjs, staged deliberately over two days:
- June 16, 07:05 UTC — npm user
sergey2016publishes[email protected], a clean, fully functional copy of dayjs. It clones dayjs’s author field (iamkun), homepage, repo URL, keywords, and 1.11.x version lineage so it survives a casual look. This decoy is the version pinned into the@mastrapackages. - June 17, 01:01 UTC —
[email protected]ships, identical except for asetup.cjsfile and apostinstallhook. Because the@mastrapackages pin^1.11.21, every fresh install resolves to the malicious1.11.22.
Eleven minutes later the scope-wide republish began. StepSecurity timestamped 13 of the highest-profile packages going out between 01:12 and 01:48 UTC — including @mastra/[email protected], @mastra/[email protected], @mastra/[email protected], @mastra/[email protected], @mastra/[email protected], @mastra/[email protected], and @mastra/[email protected] — with the full wave reaching ~144 packages.
The payload
[email protected] runs node setup.cjs --no-warnings on install. setup.cjs (~4.5 KB, obfuscated with a shuffled-alphabet Base64 scheme) disables TLS verification (NODE_TLS_REJECT_UNAUTHORIZED=0), fetches a second stage from https://23.254.164[.]92:8000/update/49890878, writes it to a random file in the temp dir, and launches it detached — node <tmp>.js 23.254.164[.]123:443 — so it outlives the install. Then it deletes itself.
Stage two is a cross-platform information stealer. Per JFrog and SafeDep it harvests browser history and data from 160+ cryptocurrency-wallet extensions, installs persistence on Windows, macOS, and Linux, exfiltrates to 23.254.164[.]123, and polls that C2 for further modules to execute. Snyk and Orca tie the tradecraft to Sapphire Sleet (BlueNoroff), the DPRK crew known for developer-targeted crypto theft — though the primary analyses stop at “crypto-stealing RAT,” so treat the attribution as a lead, not a verdict.
Why this one matters
Mastra sits at the AI-infrastructure intersection: its packages land in dev environments, CI runners, and production AI services holding exactly the secrets attackers want — ANTHROPIC_API_KEY, OPENAI_API_KEY, AWS_ACCESS_KEY_ID, GITHUB_TOKEN, NPM_TOKEN. The payload runs at install time, so exposure happens before you ever import anything.
The most useful detail is how it got through. Mastra publishes real releases from CI through npm’s trusted-publisher flow with SLSA provenance attestations — but it did not require provenance. The attacker pushed from a plain personal token with no attestations, and the same fingerprint repeats across the whole wave. As SafeDep notes, a signature-verifying install (npm audit signatures, or a policy that mandates attestations) would have rejected every package in this campaign.
What to do now
Treat any workstation, CI runner, or build host that ran npm install for an @mastra/* package after ~01:00 UTC on June 17 as compromised. Roll back to known-good versions predating the wave; npm has pulled the malicious versions from the top packages and reverted their latest tags, but check your lockfiles directly. Rotate everything reachable from those hosts — LLM API keys, cloud credentials, npm/GitHub tokens, SSH and GPG keys.
Hunt for the IOCs: outbound connections to 23.254.164.92:8000 or 23.254.164.123:443, easy-day-js in any lockfile, .pkg_history / .pkg_logs marker files in the temp dir, and stray detached node <hex>.js processes. Critically, removing the first-stage package does not kill the detached stage-two process or any persistence it has already installed — you have to hunt the host. Finally, enforce npm audit signatures or require provenance attestations in CI so an unsigned republish can’t install in the first place.
Advisories: JFrog, SafeDep, Socket, and StepSecurity; tracking issue mastra-ai/mastra#18045.