Date Observed: June 17, 2026
Ecosystem: npm (@mastra scope)
Targets: Developer workstations and CI/CD runners installing @mastra/* packages
Attack Type: Account takeover + dependency injection + typosquatting + credential-stealing RAT
Impact: Over 140 packages trojanized; ~8M weekly downloads exposed; cryptocurrency wallet and credential theft
Key Takeaways
-
- A Mastra contributor’s npm account was hijacked after scope permissions were never revoked, giving attackers write access to over 140 packages in the @mastra scope.
-
- easy-day-js mimicked the legitimate dayjs library and used a postinstall hook to execute a two-stage dropper targeting 166 cryptocurrency wallet extensions and build-time credentials.
-
- npm’s caret semver (^) automatically resolved the clean version 1.11.21 to the malicious 1.11.22, turning standard version ranges into a delivery mechanism.
-
- Mastra generated SLSA provenance attestations for legitimate CI releases, but the npm org policy did not enforce them, allowing the attacker’s unattested packages to publish freely.
-
- Any system that executed npm install against Mastra packages on June 17, 2026, should be treated as fully compromised; rotate all credentials and audit for persistence artifacts.
-
- Microsoft attributes the attack with high confidence to Sapphire Sleet (also tracked as BlueNoroff), a North Korean state actor, and ties it to the same group’s earlier Axios npm compromise.
AI development frameworks are an increasingly high-value target for software supply chain attackers. The logic is direct: compromise a framework dependency at build time, and you gain access to the most sensitive credentials in the pipeline — LLM API keys, cloud provider tokens, and CI/CD secrets that enable lateral movement across infrastructure.
On June 17, 2026, attackers compromised Mastra, a popular open-source TypeScript framework used for building AI agents and RAG pipelines. By hijacking a contributor’s npm account, they injected a malicious dependency (easy-day-js) across over 140 packages in the @mastra scope. With @mastra/core alone downloaded approximately 918,000 times weekly, the potential blast radius was wide and immediate.
Scope and Impact of the Attack
The compromise covered over 140 packages across the @mastra npm scope, mass-published within a short window on June 17. Across the full scope, affected packages reached an estimated 8 million weekly downloads at the time of compromise. The affected surface spanned the framework’s core runtime, tool integrations, agent orchestration, and RAG pipeline components.
Critically, exposure occurred at npm install, before any application code ran. Any developer workstation, CI/CD runner, or automated build system that pulled these packages during the exposure window faced potential full compromise, independent of whether they ever imported or called the affected libraries.
On June 19, 2026, Microsoft attributed this activity with high confidence to Sapphire Sleet, a North Korean state actor whose campaigns focus on cryptocurrency and credential theft, citing infrastructure and post-compromise tradecraft consistent with prior Sapphire Sleet operations. Microsoft attributes the earlier axios npm compromise to the same actor, placing both incidents in one documented campaign.
How the Attack Works
The operation combined account takeover, package mirroring, and a two-phase runtime payload.
Stage 0: Establishing the Typosquat
On June 16, 2026, the npm account sergey2016 published easy-day-js version 1.11.21. The package was a functional clone of the legitimate dayjs date library: identical version numbering, MIT license, and author metadata (iamkun). The clean decoy was designed to pass automated package structure checks.
Stage 1: Injecting the Malicious Version
The next day, easy-day-js was updated to version 1.11.22. This version introduced setup.cjs, a heavily obfuscated file, alongside a postinstall hook in package.json:
“scripts”: {
“postinstall”: “node setup.cjs –no-warnings”
}
The –no-warnings flag suppressed Node.js runtime warnings, preventing developers from noticing execution during installation.
Stage 2: Account Takeover and Mass Injection
The attacker hijacked ehindero, a legitimate Mastra contributor whose npm scope permissions were never revoked after their last publish in February 2025. Prior to the attack, the account’s registered email was changed to ehindero2016@tutamail.com, indicating credential takeover rather than insider action. The attacker published updates to over 140 packages across the @mastra scope, adding one dependency entry to each package.json:
“dependencies”: {
“easy-day-js”: “^1.11.21”
}
Because npm’s caret operator resolves to the latest compatible version, any fresh npm install against the clean 1.11.21 automatically fetched the malicious 1.11.22, published roughly 11 minutes before the republish wave began.
Stage 3: Dropper Execution and Payload Delivery
When a developer or CI runner executed npm install, the postinstall hook immediately fired setup.cjs. The obfuscated dropper executed four steps in sequence:
-
- TLS bypass: Set NODE_TLS_REJECT_UNAUTHORIZED=’0′, allowing outbound connections to attacker infrastructure by disabling cert validation.
-
- C2 fetch: Downloaded a second-stage payload from 23.254.164.92:8000/update/49890878.
-
- Process detachment: Spawned the payload with detached: true and .unref(), allowing it to persist independently of the npm install process.
-
- Self-deletion: Called fs.rmSync(__filename), removing all forensic traces from the directory.
The ~41 KB second-stage payload was a cross-platform Node.js remote access trojan (RAT) that inventoried 166 cryptocurrency wallet extensions (including MetaMask, Phantom, and Coinbase) alongside browser history from Chrome, Edge, and Brave, and opened a remote-module execution channel for follow-on theft. It established persistence via OS-specific mechanisms disguised as Node tooling: LaunchAgents on macOS, systemd services on Linux, and Windows Run registry keys. C2 communications ran through 23.254.164.123:443, Socket Research Team reports.
Why This Matters to DevOps and DevSecOps Teams
This attack executed entirely at install time; before tests run, before runtime security tools engage, and before application-level monitoring sees activity. A CI runner resolving Mastra dependencies was compromised at the package resolution step, not at code execution.
Why Existing Controls Miss This
Standard dependency scanning checks manifests, lockfiles, and known vulnerability databases. This attack bypassed all three:
-
- The Mastra packages themselves were not modified at the source level. The only change was a new dependency entry; malicious code lived entirely inside easy-day-js.
-
- The malicious version of easy-day-js was zero-day during the exposure window. No advisory existed when installs were happening.
-
- Mastra’s CI pipeline generated Sigstore-backed SLSA provenance attestations for legitimate releases, but the npm org policy did not enforce attestation as a requirement for all publishes. The attacker’s stolen-credential push dropped the attestation signature; npm accepted the packages regardless.
How InvisiRisk Protects Against This Attack
The attack depended on two conditions: a freshly published malicious dependency, and an outbound C2 call from inside the build runner. The InvisiRisk Build Application Firewall addresses each at the build layer.
Stability Buffer. The InvisiRisk BAF can block newly published packages for a configurable window (default 48 hours) before they can be consumed in a build. easy-day-js 1.11.22 was published only minutes before the @mastra package wave. Under a 48-hour buffer, the malicious version would have been blocked before any runner could resolve it. For DevSecOps teams managing CI/CD pipeline security, this is the primary structural defense against zero-day dependency injection.
Build Proxy / Network Interception. The InvisiRisk BAF operates as a network proxy inside the build environment and intercepts all outbound build-time traffic. The dropper’s callback to 23.254.164.92:8000 occurs during npm install, not at application runtime. BAF blocks that connection before any payload is fetched or executed, closing the delivery channel at the network layer. This protection applies regardless of where in the dependency tree malicious code is referenced, highlighting a core part of InvisiRisk’s software supply chain security enforcement.
Why Build-Time Defenses Matter
Mastra is not the first AI framework targeted this way, and it won’t be the last. The attack pattern — stale maintainer account, injected typosquat, execute at install, exfiltrate before detection — keeps working because it fires at install time, before tests, scanners, or runtime monitoring ever see it. That is precisely why defenses have to operate at the build layer: it is the only point where this class of attack is observable and stoppable while it happens. The pattern will keep being applied against high-value developer tooling, so the defense has to live where the attack does. Any system that ran npm install against @mastra packages on June 17, 2026, should be treated as fully compromised. Remediation steps will require: rotating credentials, removal of persistence artifacts, and an audit of the build pipeline before the next run.


