143 Mastra npm Packages Backdoored via easy-day-js Dependency Swap
June 17, 2026
TrapDoor: 34 Malicious Packages Stole Crypto Wallet Keys and SSH Credentials Across npm, PyPI, and Crates.io
May 25, 2026
AntV npm Packages Compromised via Hijacked Maintainer Account
May 19, 2026
CVE-2026-42945: NGINX Rewrite Module Heap Overflow Enables Unauthenticated Code Execution
May 13, 2026
TanStack and Mistral npm Packages Compromised in Mini Shai-Hulud Supply Chain Attack
May 11, 2026
Microsoft Patches Critical ASP.NET Core DataProtection Flaw That Breaks Cryptographic Signatures
April 23, 2026
Vercel got breached. Here is what that means for everyone downstream.
April 19, 2026
When the System Built to Warn Us Can No Longer Keep Pace
April 15, 2026
Your AI Agent Remembers Your Secrets
April 13, 2026
Your Home Directory is a Secret Goldmine for Attackers
April 6, 2026
When a core npm dependency becomes the attack path: lessons from the Axios compromise
March 31, 2026
When the AI dependency becomes the attack path: lessons from the LiteLLM PyPI compromise
March 24, 2026
When the security scanner becomes the attack path: lessons from the Trivy compromise
March 23, 2026
Critical Path Traversal Vulnerability in jsPDF Library (CVE-2025-68428)
January 6, 2026
MongoBleed: Unauthenticated Memory Disclosure in MongoDB (CVE-2025-14847)
December 27, 2025
Critical Remote Code Execution in n8n Workflow Automation: CVE-2025-68613
December 19, 2025
The Return of Shai-Hulud: npm's Worm Strikes Back
November 24, 2025
Critical Chrome Zero-Day Exploited: Google Rushes Emergency Patch for CVE-2025-0411
October 28, 2025
Critical Remote Code Execution Vulnerability in React Server Components
December 3, 2025
Supply Chain SecurityJune 17, 20266 min read

143 Mastra npm Packages Backdoored via easy-day-js Dependency Swap

On June 17, 2026, an attacker used a former contributor's stale npm access to push malicious versions of 143 @mastra packages. The payload, hidden inside a typosquatted dayjs clone, installed a cross-platform RAT with OS-level persistence on macOS, Linux, and Windows.

On June 16, 2026, at 07:05 UTC, an npm account named sergey2016 published easy-day-js@1.11.21. The package was clean. It was a fully functional copy of the legitimate dayjs date library, mirroring its author name, version numbering, homepage, repository URL, and license word for word. Its only purpose was to sit there long enough to look credible.

Eighteen hours later, at 01:01 UTC on June 17, easy-day-js@1.11.22 appeared. Twenty-six minutes after that, the ehindero npm account began republishing 143 packages across the @mastra namespace with the malicious dependency baked in. The campaign ran for 88 minutes. ehindero was a legitimate former Mastra contributor. Their scope access had simply never been revoked.

How the attack worked

Installation triggered a postinstall hook that executed an obfuscated script called setup.cjs. The first stage disabled TLS certificate verification, wrote local marker files, downloaded a second-stage payload from an attacker-controlled server, launched it as a detached process, then deleted itself. The install appeared to complete normally.

The second stage was a cross-platform Node.js remote access trojan. JFrog Security Research, who discovered and analyzed the campaign, found it collected system reconnaissance on arrival: username, hostname, OS and architecture, running processes, and installed applications. It then harvested browser history hostnames from Chrome, Brave, and Edge, and inventoried which of 166 known cryptocurrency wallet browser extensions were installed. That last step signals the campaign’s likely priority target: developers holding crypto wallet access or high-value AI infrastructure credentials.

Persistence was written before any data left the machine. On macOS, the RAT registered a LaunchAgent at ~/Library/LaunchAgents/com.nvm.protocal.plist. On Linux, it created a systemd user service at ~/.config/systemd/user/nvmconf.service. On Windows, it wrote a Registry Run key named NvmProtocal. All three survive a reboot. C2 traffic was directed to 23.254.164.92 and 23.254.164.123.

Beyond the initial collection, the RAT opened a remote module execution channel. The attacker could push arbitrary Node.js or shell commands to any compromised machine and receive output back. The recon was the first move. The channel was the foothold.

What was affected

Mastra is a JavaScript and TypeScript framework for building AI applications. @mastra/core alone had more than 918,000 weekly downloads at the time of the attack. The broader namespace was pulling an estimated 8 million installs per week across roughly 29 million monthly downloads. Mastra environments routinely hold LLM API keys, cloud provider credentials, CI/CD tokens, and database connection strings.

  • easy-day-js@1.11.22: the malicious dependency, published June 17, 2026 at 01:01 UTC. Version 1.11.21 was clean.
  • 143 @mastra packages: republished with the bad dependency starting 01:27 UTC on June 17, including @mastra/core, @mastra/ai-sdk, @mastra/auth, and the full @mastra/voice-* family.
  • Safe versions: @mastra packages predating the June 17 publish window do not contain easy-day-js. npm pulled malicious versions and reverted latest tags after the campaign was identified.

What makes this attack different

Publishing a clean version first is a deliberate technique. A package with a publication timestamp and an existing version history does not trigger newness-based detection. By the time 1.11.22 appeared, easy-day-js already looked like an established minor-version library. Socket flagged it within six minutes anyway. JFrog Curation customers using an immaturity policy were protected within 24 hours. Both catches came from behavioral signals rather than from recognizing the package as new.

The ehindero account is the other thread worth pulling. The attacker did not compromise Mastra’s codebase. They used a real account with real publish rights that had gone stale. Access reviews feel administrative until a former contributor’s credentials become the entry point for an 88-minute mass compromise. Revoking scope access when someone leaves a project is not a hygiene task; it is a blast radius decision made in advance.

What teams should do

Any npm install that resolved easy-day-js@1.11.22 as a transitive dependency should be treated as a full compromise. Start here:

  • Check lock files for easy-day-js. Search package-lock.json or yarn.lock for the string easy-day-js. Its presence confirms the malicious dependency was resolved at install time.
  • Scan for persistence artifacts. On macOS, look for ~/Library/LaunchAgents/com.nvm.protocal.plist. On Linux, check ~/.config/systemd/user/nvmconf.service. On Windows, inspect the Registry Run key NvmProtocal.
  • Rotate all credentials that were accessible during the session. LLM API keys, cloud tokens, npm publish tokens, CI/CD secrets, and cryptocurrency wallet credentials should all be cycled, in that order.
  • Review network logs for C2 contact. Filter outbound traffic for 23.254.164.92 and 23.254.164.123. Either address appearing in logs confirms the second stage connected.
  • Reinstall from clean versions. Remove easy-day-js from dependency manifests and lock files, pin @mastra packages to versions predating June 17, and run a fresh install.

The longer pattern here is not typosquatting. A dependency that published yesterday, from a single account, with a postinstall script, is worth pausing on regardless of how familiar its metadata looks. Teams that flag transitive dependencies by publication age and account history catch this category of attack before the install runs. The postinstall hook is a legitimate feature that gets misused at a steady clip, and npm has signaled plans to restrict it in v12. Until that ships, the hook remains the fastest route from a malicious package to a compromised machine.