TL;DR

A hijacked npm contributor account (ehindero) was used to inject easy-day-js — a typosquat of the popular dayjs date library — as a dependency across 145 packages (corrected from initially-reported 144) in the @mastra/* namespace (Mastra AI agent framework). The malicious easy-day-js version ran an obfuscated postinstall hook that downloaded and executed a cryptocurrency-stealing RAT, then self-deleted to remove evidence. The attack window was 01:15 – 02:36 UTC on 2026-06-17 (88 minutes). Combined weekly downloads across affected packages exceed 1.1 million. Attribution: Microsoft attributed this attack to Sapphire Sleet (BlueNoroff), a North Korean state actor (high-confidence assessment, June 20, 2026). Modus operandi matches the Axios April 2026 attack, which US and South Korean authorities also attributed to DPRK-linked actors.

What happened

Mastra is an open-source TypeScript AI agent framework (@mastra/* npm namespace) widely used to build AI-powered workflows, agents, tool integrations, and LLM orchestration pipelines. On 2026-06-17 at 01:15 – 02:36 UTC (an 88-minute window), the npm account ehindero — a legitimate Mastra contributor whose access token was hijacked — was used to publish a malicious dependency across 145 packages in the @mastra/* scope.

The attack technique — dependency injection via a typosquat — is more subtle than directly modifying the primary package:

  1. The attacker added easy-day-js as a dependencies entry (not devDependencies) in the package.json of 144 @mastra/* packages.
  2. easy-day-js is a typosquat of the legitimate dayjs date-utility library (60M+ weekly downloads). The @mastra/* packages are legitimate — their own code is unmodified — but anyone who installed them pulled in the malicious easy-day-js as a transitive dependency.
  3. The malicious easy-day-js version's postinstall hook ran an obfuscated dropper that fetched and executed a cryptocurrency-stealing RAT, then self-deleted the dropper.

Why this evades common defenses: - npm audit focuses on known CVEs in direct/transitive dependencies, not supply-chain-injected typosquats that haven't yet received a CVE. - The primary @mastra/* package code itself is clean — only the dependency tree is poisoned. - --ignore-scripts would block postinstall, but many CI systems and developer workflows do not set this flag.

Why this matters for vibe coders: Mastra is a primary AI-agent orchestration framework. Any Mastra-powered project running npm install during the exposure window installed the RAT with full developer-machine privileges. The RAT specifically targets AI-tool credentials (Anthropic/OpenAI API keys, MCP config files) alongside cloud credentials, SSH keys, and crypto wallets.

This is the sixth documented copycat wave in the Shai-Hulud/Miasma lineage (Shai-Hulud → Second Coming → Third Coming → Phantom Gyp → Hades → Mastra injection), and the first to use a dependency-injection (adding a typosquat as a dep, rather than compromising the primary package directly) as its install-time vector at this scale.

Attribution (updated 2026-06-25): On 2026-06-20, Microsoft attributed the Mastra attack to Sapphire Sleet (also tracked as BlueNoroff), a North Korean state-sponsored threat group: "Microsoft assesses with high confidence that this activity is attributable to Sapphire Sleet, a North Korean state actor that primarily targets the financial sector." Evidence: the PowerShell backdoor, tradecraft, and C2 infrastructure matched tools previously used by Sapphire Sleet; follow-on activity employed tactics consistent with the group's historical cryptocurrency-theft campaigns. The modus operandi — contributor token theft → 88-minute automated burst → cleanup — also closely matches the Axios npm compromise (April 2026), attributed to DPRK-linked actors by US and South Korean authorities.

Am I affected?

# Check if any @mastra/* packages are installed
npm ls --depth=0 2>/dev/null | grep "@mastra/"

# Check if easy-day-js is in your dependency tree
npm ls 2>/dev/null | grep "easy-day-js"

# Check package-lock.json for the typosquat
grep "easy-day-js" package-lock.json 2>/dev/null

# Check npm cache
ls ~/.npm/easy-day-js/ 2>/dev/null

# Check for any crypto-stealer persistence artifacts (common RAT IOCs)
# Look for unexpected cron/launchd/systemd entries added 2026-06-17

If you installed any @mastra/* package on 2026-06-17 between 01:15 and 02:36 UTC (or if easy-day-js appears in your package-lock.json), treat the machine as compromised and rotate all credentials.

IOCs

Type Value
Namespace @mastra/* (145 packages)
Malicious dependency easy-day-js (typosquat of dayjs)
Attack vector postinstall hook in injected easy-day-js
Payload Obfuscated two-stage dropper → crypto-stealing RAT (self-deletes)
Initial access Hijacked npm contributor account (ehindero)
Attack window 01:15 – 02:36 UTC 2026-06-17 (88 minutes)
Attribution Shai-Hulud/Miasma lineage (payload); possible DPRK link (Axios modus operandi match)
Combined affected downloads 1.1M+ weekly

If you are affected

  1. Assume full credential compromise. The RAT targets: - LLM API keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, etc.) - AI-tool config files (~/.claude/settings.json, ~/.cursor/mcp.json, MCP OAuth tokens) - Cloud credentials (AWS ~/.aws/credentials, GCP service account keys, Azure credentials) - npm tokens (~/.npmrc), GitHub tokens, SSH keys (~/.ssh/) - Crypto wallet files (Exodus, MetaMask seed phrases)
  2. Immediately rotate all credentials on any affected machine, in priority order: LLM API keys → cloud IAM credentials → npm/GitHub tokens → SSH keys.
  3. Remove from your lockfile: grep package-lock.json or yarn.lock for easy-day-js and re-run npm install against patched @mastra/* versions.
  4. Run npm audit after removing easy-day-js and upgrading @mastra/* packages.
  5. Check for persistence: look for new cron entries, LaunchAgent plists, or systemd units created on 2026-06-17 — the RAT may have installed a persistence mechanism before self-deleting.
  6. See playbooks/if-you-installed-a-bad-npm-package.md for the full credential-rotation and forensics procedure.

Prevention

  • npm install --ignore-scripts for all CI/CD and deployment installs. Note: --ignore-scripts does not block binding.gyp native-addon builds — see Phantom Gyp.
  • Add allow-scripts=false to .npmrc to suppress lifecycle scripts globally; allow-list only specific trusted native addons. Available today in npm 11.16.0; default in npm v12 (expected July 2026).
  • Monitor the full dependency tree, not just direct deps. Tools like Socket.dev, Snyk, and Aikido can alert on newly-added transitive dependencies that are typosquats or have no prior publish history.
  • Pin @mastra/* to a known-good lockfile (package-lock.json / yarn.lock) and review diffs on every npm install run in CI.
  • Scrutinize dependency additions. A newly-added easy-day-js in a well-known framework's package.json is the IOC — require human review of any package.json change from a dependency update PR.
  • prevention/package-vetting-checklist.md
  • prevention/credential-hygiene.md

Sources