Sapphire Sleet Compromises Node.js: Account Takeover, Typosquatting, and Multi-Stage Payloads in @mastra

A sophisticated supply chain attack has been identified targeting the Node.js ecosystem, attributed to the North Korean state-sponsored actor Sapphire Sleet. The campaign involved the takeover of a high-privilege npm maintainer account, which facilitated the mass deployment of poisoned packages under the @mastra scope. These packages were engineered to silently deliver a multi-stage implant, transforming routine dependency management into a critical security vulnerability.

Disclosed on June 19, 2026, the breach began when attackers successfully hijacked the ehindero maintainer identity. With administrative publish rights across the entire @mastra scope, the adversary injected a malicious dependency into over 140 distinct packages. By rapidly promoting these weaponized versions as the “latest” releases, the attackers ensured that developer workstations and CI/CD pipelines were exposed to automatic code execution during standard npm install operations.

The intrusion relied on a highly effective typosquatting strategy. The adversary published easy-day-js, a deceptive imitation of the widely used dayjs library. The attack followed a two-step deployment: first, a benign “bait” version (1.11.21) was released to establish reputation, followed immediately by a weaponized version (1.11.22). This second version introduced a postinstall hook that triggered the execution of an obfuscated dropper script named setup.cjs.

The technical elegance of the attack lay in its exploitation of semantic versioning (semver). Because the compromised @mastra packages utilized open version ranges (e.g., easy-day-js@^1.11.21), any client running an update would automatically resolve to the malicious 1.11.22 release. Crucially, the payload executed during the installation phase, meaning the malware ran even if the package was never actually imported into the application code.

According to Microsoft Security research, there is high confidence that this operation is the work of Sapphire Sleet, an actor known for targeting the global financial sector.

End-to-end attack chain from npm account takeover through mass dependency injection to second-stage payload execution.
End-to-end attack chain: From account takeover to mass dependency injection and second-stage execution. (Source: Microsoft)

This delivery mechanism effectively weaponized the dependency resolution process, placing developer credentials, cloud tokens, build artifacts, and the integrity of downstream software at immediate risk.

Technical Analysis: The Multi-Stage Payload

The initial dropper, setup.cjs, utilizes advanced evasion techniques to bypass static analysis. The script employs a rotated array of Base64-encoded strings paired with a custom decoder. To further frustrate researchers, the array is shuffled at runtime using a specific numeric seed (0x4c11d).

Once the payload is deobfuscated in memory, it executes five distinct operational phases:

  • Environment Manipulation: It sets NODE_TLS_REJECT_UNAUTHORIZED to “0” to disable TLS certificate verification, facilitating intercepted C2 communication.
  • Persistence Preparation: It writes unique tracking markers to the temporary directory.
  • C2 Communication: It establishes a connection to attacker-controlled infrastructure.
  • Payload Fetching: It retrieves a second-stage Node.js payload.
  • Execution: It spawns the second stage as a detached, hidden process.

The second-stage implant is a ~41 KB cross-platform tasking client. This component establishes persistent beacons and provides a framework for command execution via built-in Node.js and shell runners. Notably, on Windows systems, it supports reflective .NET assembly injection, allowing for sophisticated in-memory execution that avoids writing malicious files to the disk.

The weaponized easy-day-js@1.11.22 package.json showing the postinstall hook.
The weaponized [email protected] package.json. The postinstall hook automatically triggers setup.cjs during installation. (Source: Microsoft)

Once the implant achieves Command and Control (C2) connectivity, the attackers have extensive capabilities. They have been observed downloading PowerShell backdoors, escalating privileges, and establishing deep persistence through Windows Registry Run keys, macOS LaunchAgents, or Linux systemd user units. In many cases, they successfully disabled Windows Defender by adding specific exclusions or installed service-level DLLs to gain SYSTEM context access.

The campaign’s ultimate objective appears to be financial theft. The malware includes reconnaissance routines specifically designed to enumerate browser profiles, installed applications, and a hardcoded list of 166 cryptocurrency wallet extension identifiers. Exfiltration is conducted over HTTPS, masked by a spoofed legacy IE8 User-Agent and a custom ICAP-style POST scheme to blend in with legitimate web traffic.

The decoded string table revealing C2 addresses and file system operations.
The decoded string table, revealing the C2 infrastructure, file system operations, and process spawning logic. (Source: Microsoft)

Detection and Incident Response

The compromise was flagged by anomalies in the publishing workflow. Microsoft noted that easy-day-js was published via an anonymous Tutamail address rather than the expected GitHub Actions OIDC pipeline used by the maintainer. Additionally, the only change in the package metadata was the addition of the malicious dependency.

Immediate Remediation Actions:

Security teams should operate under the assumption that any environment that performed an npm install or npm update during the attack window may be compromised. Recommended hunting steps include:

  • Process Monitoring: Scan for unexpected Node.js processes spawned by installer hooks.
  • Artifact Hunting: Search for .pkg_history or .pkg_logs markers in temp directories.
  • Persistence Checks: Inspect for NvmProtocal, com.nvm.protocal.plist, or nvmconf.service.
  • EDR/AV Review: Utilize Microsoft Defender and other EDR tools to hunt for suspicious Node.js execution patterns, reflective loading, and known C2 communication signatures.

The npm security team has since removed the compromised packages and revoked all publish access for the @mastra scope.

Related Articles

Back to top button