North Korean Hackers Poison Mastra AI in npm Attack
The compromise of the Mastra AI framework exposes critical gaps between CI/CD provenance and registry-level publish permissions.
AI frameworks have quickly become the crown jewels of modern developer environments. Because they orchestrate LLM integrations, they routinely handle highly sensitive API keys, cloud credentials, and database connection strings. This concentration of secrets has made them prime targets for sophisticated state-sponsored actors.
On June 17, 2026, Sapphire Sleet (also known as BlueNoroff), a North Korean threat actor targeting the financial and cryptocurrency sectors, executed a swift supply-chain attack against Mastra AI, a popular open-source JavaScript and TypeScript framework for building AI applications. By hijacking a single maintainer account, the attackers poisoned over 140 packages in the @mastra scope on npm within an 88-minute window.
This attack is not just another credential-theft story. It is a masterclass in exploiting the structural seams of the modern JavaScript ecosystem: the disconnect between source-code provenance and registry publishing, the persistence of stale maintainer access, and the dangerous default behavior of package installation hooks.
The Anatomy of the 88-Minute Blitz
The compromise began not with a zero-day exploit in Mastra's code, but with classic social engineering. A threat actor posing as a contact on LinkedIn targeted "ehindero," an active Mastra employee and maintainer. During a call, the maintainer clicked a suspicious link, leading to a workstation compromise and the theft of their npm credentials.
The "ehindero" account possessed publishing rights across the entire @mastra scope. Although the account had been dormant for 16 months prior to the attack, npm's lack of credential expiration meant this access remained a live, unmonitored backdoor.
With access secured, Sapphire Sleet staged the attack using a clever "clean-then-armed" dependency injection technique:
- The Decoy: On June 16, 2026, an anonymous account named "sergey2016" published
easy-day-js@1.11.21. This was a clean, fully functional clone of the legitimate, highly populardayjsdate library. - The Weaponization: On June 17, 2026, at 1:01 AM UTC, the attacker published version
1.11.22ofeasy-day-js. This version contained a malicious postinstall hook. - The Mass Poisoning: Starting at 1:15 AM UTC, the compromised "ehindero" account mass-published updated versions of 141 packages across the
@mastrascope. None of these packages contained malicious code directly. Instead, the attacker modified theirpackage.jsonfiles to includeeasy-day-js@^1.11.21as a new dependency.
Because Mastra packages used caret-range dependency resolution (^1.11.21), any developer or CI/CD pipeline running npm install or npm update was automatically served the weaponized 1.11.22 version.
Inside the Postinstall Payload
The payload execution relied on npm's default execution of lifecycle scripts. When a poisoned Mastra package was installed, the transitive dependency easy-day-js triggered a postinstall hook running node setup.cjs --no-warnings.
The execution chain proceeded in two distinct stages:
- First-Stage Dropper: The
setup.cjsscript was a 4,572-byte obfuscated file. To evade network-level security controls, the script disabled Transport Layer Security (TLS) certificate verification. It then dropped local tracking markers (~/.pkg_historyand~/.pkg_logs), contacted an attacker-controlled command-and-control (C2) server at23.254.164[.]92:8000, and downloaded a second-stage payload namedprotocal.cjs. The dropper then executed this payload as a detached, window-hidden Node.js process and deleted itself to minimize forensic footprints. - Second-Stage Implant: The downloaded implant was a highly sophisticated, cross-platform information stealer designed to target Windows, macOS, and Linux. It performed extensive host reconnaissance—collecting hostnames, system architectures, running processes, and installed applications. Crucially, it targeted developer assets:
- Browser History: It extracted history and credentials from Chrome, Edge, and Brave by directly querying local SQLite databases via
node:sqlite. - Cryptocurrency Wallets: It specifically scanned for the presence of 166 cryptocurrency wallet browser extensions, including MetaMask, Phantom, Coinbase Wallet, Binance Wallet, and TronLink.
- Persistence: To survive reboots, the malware established platform-specific persistence mechanisms:
- Windows: A registry Run key named
NvmProtocalthat launched a hidden PowerShell process. - macOS: A LaunchAgent plist named
com.nvm.protocal.plist. - Linux: A systemd user service named
nvmconf.service.
- Windows: A registry Run key named
- Browser History: It extracted history and credentials from Chrome, Edge, and Brave by directly querying local SQLite databases via
All exfiltrated data was sent to a secondary C2 server at 23.254.164[.]123:443 using a spoofed User-Agent (Mozilla/4.0 compatible; MSIE 8.0) over a custom ICAP-style protocol.
The Developer Angle: Fixing the Provenance and Token Gap
For developers, this incident exposes a glaring security gap in how we publish and consume open-source packages.
Mastra's maintainers had implemented modern security best practices: they shipped official releases from CI/CD pipelines using npm's trusted publisher flow, which generated Sigstore-signed SLSA (Software Artifacts for Source Aligned) provenance attestations.
However, npm does not enforce provenance by default. While Mastra's legitimate releases carried attestations, the registry still accepted the attacker's publications because they were signed with a standard personal access token. The attacker simply bypassed the CI/CD pipeline entirely, published the poisoned packages directly from the hijacked account, and dropped the provenance attestations. Because npm's client does not reject un-attested packages by default, downstream developers were none the wiser.
To defend against this class of attack, developers must implement a multi-layered defense-in-depth strategy.
1. Enforce Signature and Provenance Verification
Do not rely on the registry to block un-attested updates. You can configure your package manager or CI/CD pipelines to require valid signatures and provenance attestations. For example, you can use tools like npm audit signatures or integrate policy engines that reject any package in a known scope (like @mastra) that lacks a valid SLSA attestation linking it back to the official GitHub repository.
2. Neutralize Postinstall Hooks
The entire execution chain of this attack relied on the postinstall hook of a transitive dependency. If your application does not strictly require install-time scripts, disable them globally or per-project.
You can disable scripts globally via your shell:
npm config set ignore-scripts true
Alternatively, add this to your project's local .npmrc file to ensure all team members and CI runners inherit the setting:
ignore-scripts=true
If certain dependencies require scripts to build native bindings, use selective tools like allow-scripts to whitelist only trusted packages.
3. Audit and Remediate
If you ran npm install or npm update on a project containing Mastra dependencies on June 17, 2026, your environment must be treated as compromised.
- Search for Indicators of Compromise (IoCs): Check for the presence of the tracking files
~/.pkg_historyand~/.pkg_logson your system. - Check Persistence Artifacts:
- On macOS, inspect
/Users/<username>/Library/LaunchAgents/com.nvm.protocal.plist. - On Linux, check for
~/.config/systemd/user/nvmconf.service. - On Windows, inspect the registry path
HKCU\Software\Microsoft\Windows\CurrentVersion\Runfor theNvmProtocalkey.
- On macOS, inspect
- Rotate Credentials: Because the second-stage implant targets browser-stored credentials and environment variables, immediately rotate all API keys, SSH keys, and cloud credentials access tokens used on the affected machine.
The Limits of Static Scanning
The Mastra supply chain attack demonstrates that static, CVE-based vulnerability scanners are no longer sufficient. Because the malicious code was introduced via a newly published, typosquatted transitive dependency (easy-day-js), there was no pre-existing CVE for scanners to flag. The attack was a zero-CVE event that succeeded by exploiting trust.
To counter state-sponsored actors like Sapphire Sleet, who previously targeted the Axios HTTP client in April 2026 using similar tactics, the industry must transition toward behavioral monitoring at install time. Sandboxing package installations, enforcing strict provenance verification, and treating postinstall hooks as active exploit surfaces are no longer optional security postures—they are the baseline requirements for developing in the modern AI era.
Sources & further reading
- Microsoft links Mastra AI supply chain attack to North Korean hackers — bleepingcomputer.com
- From package to postinstall payload: Inside the Mastra npm supply chain compromise by Sapphire Sleet | Microsoft Security Blog — microsoft.com
- Mastra npm Supply Chain Attack Backdoors 144 Packages | AI Weekly — aiweekly.co
- 145 Mastra npm Packages Compromised via Hijacked Contributor Account — thehackernews.com
- npm and Mastra AI: Hackers Compromise 140+ Mastra npm Packages to Steal Credentials — blog.rankiteo.com
Emeka has spent over a decade tracking threat actors, vulnerability disclosures, and the evolving landscape of application security, bringing a sharp continent-spanning perspective to his reporting. He's known for translating dense CVE advisories into clear, actionable context that developers and security teams alike actually read.
Discussion 0
No comments yet
Be the first to weigh in.