top of page

144 AI-Framework Packages Backdoored in 88 Minutes: The Mastra easy-day-js Hit and the Contributor Token Nobody Revoked

  • Writer: Patrick Duggan
    Patrick Duggan
  • 29 minutes ago
  • 4 min read

On June 17, 2026, somebody logged in as a former Mastra contributor whose npm access had never been turned off, and in 88 minutes republished 144 packages in the @mastra namespace — the framework a lot of you are using to build AI agents — each one carrying a credential-stealing dropper that fires the moment you run npm install. @mastra/core alone pulls more than 918,000 weekly downloads. The window between the first poisoned publish and the rest of the wave was an hour and a half. If your CI ran an install during that window, the question isn't whether you were exposed. It's what you've rotated since.


We've been tracking this family of attack since December 4, 2025, when we took apart Shai-Hulud V2. This is the same physics with a new coat of paint, and the target surface has sharpened: it's not random typosquats anymore, it's the AI-tooling namespaces specifically. Mini Shai-Hulud hit SAP npm and pivoted to target Claude Code on April 29. Miasma backdoored 95 Red Hat npm packages on June 1. Phantom Gyp walked around --ignore-scripts through binding.gyp and hit 57 packages on June 3. Now it's the @mastra agent framework on June 17. Four hits, six weeks, all aimed at the dependencies AI developers can't build without.



How it worked


The attacker didn't break npm's signing. They didn't need to. They used a key that was already trusted.


The hijacked account, ehindero, belonged to a legitimate former Mastra contributor whose scope access was never revoked after they moved on. That is the entire ballgame. A stale publish token on a high-trust namespace is worth more than any zero-day, because the chain of trust signs for the attacker willingly. This is exactly the danger we keep flagging in malicious-package triage: a narrow bad version inside a trusted package is far more dangerous than ten thousand throwaway impostors, because the impostor has zero installs and the trojanized real package has a million.


The delivery dependency was easy-day-js, a typosquat of the popular dayjs date library, published by a separate npm account, sergey2016 (registered to [email protected]). The staging was patient. On June 16 at 07:05 UTC, [email protected] was published completely clean — a working dayjs clone, nothing malicious, the bait. The affected Mastra packages were then republished declaring a dependency on easy-day-js at version ^1.11.21, which looks like an ordinary, boring dependency bump to anyone reviewing the diff. Then, on June 17 at 01:01 UTC, [email protected] was published with the weapon inside it — a malicious setup.cjs dropper wired to the postinstall hook. Eleven minutes later, at 01:12 UTC, the automated republishing of 140-plus @mastra packages began. By 02:39 UTC it was done.


The postinstall hook ran node setup.cjs --no-warnings automatically during install — before you ever imported a single line of the package. The 4,572-byte dropper disabled TLS certificate validation, wrote install beacons into the OS temp directory (a .pkg_history file recording the install path and a .pkg_logs file holding the XOR-encoded package name), then pulled a second-stage cross-platform infostealer down from the C2, wrote it to the temp directory as a 24-hex-character .js file, launched it in a detached background process, and deleted itself to wipe the forensic trail.


The second stage is a full cross-platform RAT. It harvests LLM API keys, cloud-provider credentials, and CI/CD secrets from the environment; it inventories data from more than 160 cryptocurrency wallet browser extensions; it scrapes browser history; and it installs login persistence on all three major operating systems before exfiltrating everything home.



The indicators


Here are the IOCs, and here is the part that matters to us: when we ran both C2 addresses against our own corpus this morning, both came back clean — not previously indexed anywhere in our 1.1-million-record IOC store. So we're logging them now.


The two command-and-control addresses are 23.254.164[.]92, used for stage-two payload retrieval over port 8000, and 23.254.164[.]123, used for data exfiltration over port 443. Note the shape: two roles, two addresses, one /24. Staging and exfil split across adjacent hosts on the same prefix is itself a signature — it tells you the operator provisioned dedicated infrastructure rather than reusing a single box, and it gives a defender a prefix to watch, not just an address. The C2 request path on both hosts is /49890878.


On the host side, the persistence artifacts are worth feeding straight into your EDR. On macOS: a NodePackages folder under ~/Library holding config.json and protocal.cjs, plus a LaunchAgent at ~/Library/LaunchAgents/com.nvm.protocal.plist. On Linux: ~/.config/NodePackages/config.json, a protocal.cjs under ~/.config/systemd/nvmconf/, and a user service at ~/.config/systemd/user/nvmconf.service. On Windows: C:\ProgramData\NodePackages\config.json and protocal.cjs, plus a registry Run key named NvmProtocal. The misspelling of "protocol" as "protocal" is consistent across all three platforms and makes a clean, low-false-positive hunting string. The malicious package versions to pin and purge are easy-day-js 1.11.21 and 1.11.22.


The discovery was a genuine multi-vendor effort — Endor Labs, JFrog, SafeDep, Socket, and StepSecurity all surfaced it within hours. Credit where it's due; the named-malicious data underlying this writeup is theirs.



What to actually do


If you build with Mastra, the install-time clock already ran. Treat any environment that ran npm or pnpm install on June 17 as exposed and rotate on visibility, not on evidence of abuse — your LLM keys, cloud credentials, and CI/CD tokens, in that order. Logs are forensic, not exonerating. Pin away from the poisoned easy-day-js versions, hunt the "protocal" persistence artifacts, and block the 23.254.164[.]92 and 23.254.164[.]123 pair at your egress.


This is the through-line we keep coming back to: the AI-framework supply chain is now a primary target, not a curiosity, and the cheapest way in is still a forgotten credential on a trusted account. We don't guarantee we caught everything — we cap our certainty at 95% on purpose. But the IOCs above are clean, named, and now indexed, and the defensive move is the same one it's been all year. Watch the door, not the actor.




The threat feed this post is built on

1.14M+ IOCs, STIX 2.1, precursor signals, supply-chain detection. Free API key in 30 seconds.


bottom of page