Skip to content
PERMISSION/PROTOCOL
Back to incident tracker

2026-06-17

HighPrimary

Mastra npm supply chain attack backdoors 144 AI agent packages via easy-day-js typosquat, delivering cross-platform RAT targeting LLM API keys

144 @mastra npm packages were backdoored on June 17, 2026 via hijacked contributor account and easy-day-js typosquat, deploying a cross-platform RAT that steals LLM API keys, cloud credentials, and crypto wallets.

Mastra / npmCredential exposurenpm supply chain compromise / RAT deliverynpm registry / Developer workstations / CI/CD runners / AI agent environments

What happened

Attacker authenticated with a 16-month-dormant Mastra contributor account, automated publication of 144 package versions each adding easy-day-js as a dependency, triggering postinstall RAT execution on any host that ran npm install against affected versions between 01:12-02:39 UTC.

Why it matters

Any developer workstation, CI/CD runner, or build environment that ran npm install against a @mastra/* package on June 17, 2026 between 01:12-02:39 UTC should be treated as compromised. The RAT harvests LLM API keys, cloud provider credentials, CI/CD tokens, npm tokens, crypto wallet extensions, and browser history, then establishes a persistent remote execution channel that survives npm uninstall.

Missing authorization check

Not applicable: no agent authorization boundary was crossed in this incident.

Would PP block it?

The compromise ran through package, credential, or vendor infrastructure rather than through an agent tool call, so there is no agent action for an authorization gate to hold.

Incident analysis

Timeline and technical read

Timeline

  1. 2026-06-16

    Attacker pre-positions [email protected] on npm as a clean bait version with no malicious payload, establishing presence and passing initial audits.

  2. 2026-06-17

    01:01-01:12 UTC: Attacker authenticates with dormant Mastra contributor account (ehindero) and prepares malicious [email protected] with obfuscated postinstall dropper.

  3. 2026-06-17

    01:12-02:39 UTC: Automated campaign publishes 144 @mastra/* package versions each adding easy-day-js as a dependency. @mastra/core and all major packages affected.

  4. 2026-06-17

    SafeDep, StepSecurity, and Socket Security independently detect the campaign. C2 infrastructure (23.254.164.92, 23.254.164.123) confirmed active. Mastra team notified.

  5. 2026-06-17

    Mastra deprecates all affected package versions, revokes compromised contributor access. npm removes malicious tarballs. No CVE assigned - traditional CVE-based scanners had zero coverage.

Technical breakdown

  • easy-day-js was engineered to survive code review: it copied dayjs's npm author name, homepage URL, repository URL, license, and version numbering (1.11.21 to 1.11.22) verbatim. The only distinguishing signals were the npm maintainer account (sergey2016) and the presence of setup.cjs.
  • The postinstall dropper (setup.cjs, 4,572 bytes, obfuscated) fetches and executes the second-stage RAT payload. Execution happens at npm install time, before any application code runs - making it invisible to runtime security monitors.
  • The RAT installs OS-level persistence across all three major platforms: Windows Run key, macOS LaunchAgent plist, Linux systemd user unit. This persistence survives npm uninstall; only explicit IOC removal restores a clean state.
  • The payload specifically inventories 166 cryptocurrency wallet browser extensions (Chrome, Brave, Edge) and harvests full browser history - targeting the developer profile of an AI agent framework user who likely holds both crypto assets and LLM API keys in the same browser profile.
  • No CVE was assigned. The attack vector (typosquatted transitive dependency via compromised contributor account) has no entry in CVE-based scanner rulesets. Organizations relying solely on CVE-gated SCA tools had zero detection coverage at time of exploitation.

Authorization boundary

Where the authorization boundary should have been

This incident is categorized as Credential exposure. The relevant Permission Protocol gate is Credential Gate. The read is conditional: the block only applies where the real action boundary is routed through a gate.

If enforced at
Downstream agent action authorization using extracted credentials
Still needs
npm publish-time scope access control; package install-time postinstall hook execution; supply chain integrity verification at dependency resolution time
Receipt required for
npm publish to @mastra scope for any contributor inactive >90 days; access to LLM API keys or cloud credentials from environments that executed npm install against unverified packages

No agent took an action in this incident. Permission Protocol gates what an agent does, so it does not apply where the harm required no agent action.

Start small

Put the relevant gate at this action boundary.

This incident maps to Credential Gate. Start with the boundary that controls the actual action, then require a signed receipt before execution.

Replay this incident with a signer in the loop