Skip to main content
Sign in

Audit log

Every state-changing event for easy-day-js / Mastra npm Supply Chain Attack: moderation decisions on community submissions, plus corrections and updates from the news pipeline. URL-based decisions carry three independent witnesses — the original source, an Internet Archive snapshot taken at submission time, and a Solana memo signed by our publicly-disclosed publisher key.

  1. #1publishby system:backfill
    2026-06-17 17:04:02Z
    Score: ?? (no score change)
    anchoranchored
    chain
    mainnet-betaslot 427,111,768
    sig
    HmGSnnDZaEzQ…EAwBhQZqexplorer ↗
    hash
    EQ3Wx6xGDUJs…6iv32fLxsha256 → base58
    verifying row…full verify ↗
    canonical bytes (24583 B) ▸
    {"actor":"system:backfill","investigation_id":"74e7fe61-1653-41fd-8387-da3b715275e2","kind":"publish","page_slug":"easy-day-js-mastra-npm-supply-chain-attack","published_at":"2026-06-17T17:04:02.566Z","sequence_num":1,"snapshot":{"content_type":"investigation","entity_name":"easy-day-js / Mastra npm Supply Chain Attack","sections":[{"content":"The easy-day-js supply chain attack targeted the Mastra AI framework's npm organization (@mastra) in a coordinated two-phase operation spanning June 16–17, 2026. Attackers first established a credible malicious package (easy-day-js) disguised as the popular dayjs date library, then leveraged a compromised contributor account with unrevoked scope permissions to mass-publish trojanized versions of 141–144 Mastra packages within approximately 88 minutes. The attack exploited npm's dependency version resolution logic: packages were published with the dependency pinned using caret notation (\"^1.11.21\"), which caused fresh installations to automatically resolve to the armed version 1.11.22. No vulnerability in npm software was exploited; the attack relied entirely on social engineering, stale access management, and ecosystem trust mechanisms.","heading":"Attack Overview","severity":"critical","sources":[{"credibility":2,"name":"Mastra npm Supply Chain Attack: 140+ Packages Backdoored via easy-day-js Typosquat — StepSecurity","type":"research","url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"},{"credibility":2,"name":"140+ Mastra npm Packages Compromised in Coordinated Supply Chain Attack — Socket","type":"research","url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"credibility":2,"name":"easy-day-js Supply Chain Attack Hits Mastra AI in npm — OX Security","type":"research","url":"https://www.ox.security/blog/easy-day-js-supply-chain-attack-hits-mastra-ai-in-npm/"}]},{"content":"The attack entry point was the npm account ehindero, which had belonged to a legitimate former Mastra contributor. According to Snyk's analysis, the attacker changed the account's email to ehindero2016@tutamail.com, indicating a full account takeover rather than token theft alone. The ehindero account had been dormant for approximately 16 months prior to the attack. Crucially, the account's scope publishing rights for the @mastra npm namespace were never revoked after the contributor's departure — npm has no built-in scope-permission expiration policy. This single stale credential was sufficient to publish packages across the entire @mastra scope. The GitHub issue filed by Mastra (issue #18061) states that the compromised maintainer was an active Mastra employee whose account was compromised through social phishing via a fraudulent LinkedIn message; the maintainer clicked a suspicious link while on a call. A separate npm account, sergey2016 (using email sergey2016@tutamail.com), is identified in technical reports as the account that first published the malicious easy-day-js package.","heading":"Initial Access: Compromised npm Account and Stale Permissions","severity":"critical","sources":[{"credibility":2,"name":"Mastra npm Scope Takeover — Snyk Blog","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"},{"credibility":1,"name":"Mastra GitHub Issue #18061 — Official Incident Report","type":"official","url":"https://github.com/mastra-ai/mastra/issues/18061"},{"credibility":2,"name":"144 Mastra npm Packages Compromised via Hijacked Contributor Account — The Hacker News","type":"news_article","url":"https://thehackernews.com/2026/06/144-mastra-npm-packages-compromised-via.html"}]},{"content":"The package easy-day-js was published to npm by account sergey2016 as a typosquat of the widely-used dayjs date library. Version 1.11.21, published June 16, 2026 at 07:05 UTC, was a complete, functional copy of dayjs with no malicious code — its purpose was to establish a credible package history and bypass superficial automated checks. Version 1.11.22, published June 17, 2026 at 01:01 UTC, introduced an obfuscated postinstall dropper (setup.cjs, approximately 4,572 bytes). The obfuscation employed three layers: custom-alphabet Base64 encoding, array rotation with integrity checks, and XOR-encoded markers. Twenty-six minutes after easy-day-js 1.11.22 was published, the ehindero account began mass-publishing trojanized Mastra packages that listed easy-day-js with caret-pinned version range \"^1.11.21\", ensuring any fresh npm install would resolve to the weaponized 1.11.22 release.","heading":"Malicious Package: easy-day-js Typosquat","severity":"critical","sources":[{"credibility":2,"name":"Mastra npm Supply Chain Attack — StepSecurity","type":"research","url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"},{"credibility":2,"name":"easy-day-js: Supply Chain Campaign Targets Mastra npm Packages — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"},{"credibility":2,"name":"Mastra npm Scope Takeover — Snyk Blog","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"}]},{"content":"The malicious payload operated in two stages. Stage 1 (setup.cjs) was a lightweight loader that executed at npm install time via the postinstall hook. It disabled TLS certificate verification by setting NODE_TLS_REJECT_UNAUTHORIZED=0, wrote an installation beacon to a temporary file (.pkg_history), downloaded the second-stage payload from the attacker-controlled server at 23.254.164.92:8000 using campaign path /49890878, and spawned a detached background process before self-deleting to remove forensic evidence. Stage 2 (protocal.cjs, approximately 41 KB) was a cross-platform Node.js remote access trojan that established command-and-control communication with 23.254.164.123 on port 443, beaconing approximately every 10 minutes. Its reconnaissance capabilities included: system fingerprinting (OS, architecture, Node.js version, running processes), browser history extraction from Chrome, Edge, and Brave via SQLite databases, hostname enumeration, and a cryptocurrency wallet inventory that matched 166 known wallet browser extension IDs including MetaMask, Phantom, Solflare, and Coinbase Wallet. The initial beacon transmitted the full wallet extension inventory to the attacker, enabling targeted follow-on module delivery. The malware installed persistent mechanisms under the name NvmProtocal: a LaunchAgent (com.nvm.protocal.plist) on macOS, a systemd user service (nvmconf.service) on Linux, and an HKCU Run registry key on Windows. Signal handlers were registered to re-install persistence if the process was killed.","heading":"Payload Technical Analysis: Two-Stage RAT and Infostealer","severity":"critical","sources":[{"credibility":2,"name":"easy-day-js: Supply Chain Campaign Targets Mastra npm Packages — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"},{"credibility":2,"name":"140+ Mastra npm Packages Compromised — Socket","type":"research","url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"credibility":2,"name":"Mastra npm Supply Chain Attack — StepSecurity","type":"research","url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"}]},{"content":"Between 01:12 and 02:39 UTC on June 17, 2026 — a window of approximately 88 minutes — the compromised ehindero account published between 141 and 144 malicious packages across the @mastra npm namespace, with varying package counts cited across security researchers (141 per OX Security and StepSecurity, 143 per JFrog, 144 per Snyk and The Hacker News). Affected packages included @mastra/core, which alone recorded over 918,000 weekly downloads at the time of the incident. OX Security reported combined weekly downloads across affected packages of approximately 8,031,590 and monthly downloads of approximately 29,230,561; StepSecurity and Socket reported combined figures exceeding 1.1 million weekly downloads across compromised versions specifically. Core infrastructure packages, database adapters, and integration modules were among those trojanized. Any developer or CI/CD pipeline that executed npm install against a Mastra-dependent project during the exposure window — without a committed lockfile or install script blocking — may have had the postinstall dropper execute on their machine. Environments likely to hold high-value targets included LLM API keys, cloud provider credentials, CI/CD tokens, SSH keys, and cryptocurrency wallet browser extensions.","heading":"Scope and Impact","severity":"critical","sources":[{"credibility":2,"name":"easy-day-js Supply Chain Attack Hits Mastra AI in npm — OX Security","type":"research","url":"https://www.ox.security/blog/easy-day-js-supply-chain-attack-hits-mastra-ai-in-npm/"},{"credibility":2,"name":"144 Mastra npm Packages Compromised via Hijacked Contributor Account — The Hacker News","type":"news_article","url":"https://thehackernews.com/2026/06/144-mastra-npm-packages-compromised-via.html"},{"credibility":2,"name":"easy-day-js: Supply Chain Campaign — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"}]},{"content":"The stage-2 payload specifically enumerated 166 cryptocurrency wallet browser extension IDs across Chrome, Brave, and Edge profiles — including MetaMask, Phantom, Solflare, and Coinbase Wallet — and transmitted this inventory to attacker-controlled infrastructure on first beacon. This reconnaissance data enabled operators to identify victims with high-value crypto holdings and deliver targeted follow-on modules for credential extraction. Any developer who ran npm install against affected Mastra packages during the exposure window on a machine with active cryptocurrency wallet browser extensions should be considered potentially compromised. Security researchers across JFrog, Socket, StepSecurity, Snyk, and OX Security uniformly recommend treating any such environment as fully compromised: migrating all cryptocurrency funds to fresh wallets generated on a clean, unaffected device, and rotating all credentials present in the environment.","heading":"Cryptocurrency Wallet Risk","severity":"critical","sources":[{"credibility":2,"name":"easy-day-js: Supply Chain Campaign — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"},{"credibility":2,"name":"140+ Mastra npm Packages Compromised — Socket","type":"research","url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"credibility":2,"name":"Mastra npm Scope Takeover — Snyk Blog","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"}]},{"content":"Network indicators: C2 stage-1 payload server at 23.254.164.92 port 8000 (campaign path /49890878); C2 stage-2 command-and-control server at 23.254.164.123 port 443. Host artifacts: file .pkg_history written to the system temp directory; file protocal.cjs and directory NodePackages dropped by the stage-2 implant; file .pkg_logs. Persistence artifacts by platform — macOS: ~/Library/LaunchAgents/com.nvm.protocal.plist; Linux: ~/.config/systemd/user/nvmconf.service; Windows: HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run key named NvmProtocal. Attacker-controlled npm accounts: ehindero (compromised former contributor account, email changed to ehindero2016@tutamail.com); sergey2016 (account that published easy-day-js, email sergey2016@tutamail.com). Malicious package versions: easy-day-js 1.11.22 (containing setup.cjs); all @mastra/* packages published by ehindero between 01:12 and 02:39 UTC on June 17, 2026.","heading":"Indicators of Compromise","severity":"critical","sources":[{"credibility":2,"name":"Mastra npm Supply Chain Attack — StepSecurity","type":"research","url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"},{"credibility":2,"name":"140+ Mastra npm Packages Compromised — Socket","type":"research","url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"credibility":2,"name":"Mastra npm Scope Takeover — Snyk Blog","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"}]},{"content":"According to the official GitHub issue #18061, the Mastra team became aware of the attack at approximately 8:45 PM PT on June 16, 2026, and immediately contacted npm and security partner Socket Security. By 11:57 PM PT, 110 compromised packages had been unpublished and 6 deprecated (npm prevented full unpublishing of those 6). Safe package versions were published around 1:00 AM PT on June 17, 2026 via pull request #18056, which also removed the token bypass vulnerability that had allowed the attacker to circumvent MFA requirements. The team verified that source code in all repositories was clean — the malicious dependency was injected at npm publish time rather than in the git repository itself. The Mastra team committed to reducing credential exposure, enhancing MFA enforcement, implementing federated identity solutions, and conducting a broader access audit to revoke stale contributor permissions. JFrog reported their automated systems flagged all compromised versions within 24 hours, enabling automatic fallback to compliant versions for customers using their tooling.","heading":"Mastra Team Response and Remediation","severity":"high","sources":[{"credibility":1,"name":"Mastra GitHub Issue #18061 — Official Incident Report","type":"official","url":"https://github.com/mastra-ai/mastra/issues/18061"},{"credibility":2,"name":"easy-day-js: Supply Chain Campaign — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"}]},{"content":"Security researchers across multiple firms identified systemic npm ecosystem vulnerabilities exploited in this attack. First, npm has no built-in policy for automatically expiring scope publishing permissions on dormant accounts — the ehindero account had been inactive for approximately 16 months before the attack, yet retained full publishing rights to the entire @mastra scope. Second, npm's support for MFA token bypass allowed the attacker to publish without satisfying multi-factor authentication even where MFA was nominally required. Third, npm's postinstall hook mechanism allows arbitrary code execution at install time with no sandboxing, no opt-in requirement from the consuming developer, and no network egress restriction. OX Security noted that npm v12 (estimated July 2026) is expected to deprecate install scripts, potentially closing this attack vector; researchers suggested attackers may intensify reliance on postinstall hooks before that deprecation takes effect. StepSecurity demonstrated that network egress monitoring (via Harden Runner) successfully blocked the C2 connections in testing, offering a detection path even when the malicious code executes.","heading":"Systemic Risk: npm Access Management and Install Scripts","severity":"high","sources":[{"credibility":2,"name":"easy-day-js Supply Chain Attack Hits Mastra AI in npm — OX Security","type":"research","url":"https://www.ox.security/blog/easy-day-js-supply-chain-attack-hits-mastra-ai-in-npm/"},{"credibility":2,"name":"Mastra npm Scope Takeover — Snyk Blog","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"},{"credibility":2,"name":"Mastra npm Supply Chain Attack — StepSecurity","type":"research","url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"}]},{"content":"No threat actor group has been publicly attributed to this attack by any government agency or major threat intelligence firm as of the date of this investigation. The campaign identifier EASY_DAY_JS_MASTRA_2026 appears in phoenix.security's analysis. The two npm accounts involved — sergey2016 and the compromised ehindero — used tutamail.com addresses (a privacy-focused email service), which is a common operational security practice among financially motivated threat actors but does not provide attribution. The sophistication of the attack — pre-staging a clean package version, using caret dependency notation to ensure automatic version resolution to the malicious release, and deploying a cross-platform persistent RAT rather than a simple credential harvester — suggests organized rather than opportunistic threat activity. JFrog noted that an identical loader was detected on public sandboxes approximately 19 days before the Mastra attack (around May 29, 2026), indicating toolkit reuse and a longer operational campaign.","heading":"Attribution","severity":"medium","sources":[{"credibility":2,"name":"easy-day-js: Supply Chain Campaign — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"},{"credibility":2,"name":"easy-day-js / EASY_DAY_JS_MASTRA_2026 — Phoenix Security","type":"research","url":"https://phoenix.security/easy-day-js-mastra-npm-supply-chain-typosquat-rat-2026/"}]},{"content":"Security researchers across multiple firms recommend the following steps for any developer or organization that may have been exposed. Immediate: (1) Treat any system on which an affected @mastra package version was installed between 01:01 UTC June 17 and the time of remediation as potentially fully compromised. (2) Migrate all cryptocurrency holdings to fresh wallets generated on a verified clean device with new seed phrases. (3) Rotate all credentials that may have been present in the environment: npm tokens, GitHub tokens, cloud provider API keys (AWS, GCP, Azure), SSH keys, LLM API keys, CI/CD secrets. (4) Remove persistence artifacts: delete com.nvm.protocal.plist on macOS, nvmconf.service on Linux, and the NvmProtocal registry key on Windows; check for protocal.cjs and NodePackages files. Preventive for future projects: use committed lockfiles (package-lock.json) and npm ci in CI pipelines to prevent silent dependency re-resolution; disable install scripts by default (npm config set ignore-scripts true or --ignore-scripts flag); implement network egress monitoring in CI; require SLSA provenance on package consumption; audit and revoke stale contributor scope permissions regularly.","heading":"Developer Remediation Guidance","severity":"high","sources":[{"credibility":2,"name":"Mastra npm Scope Takeover — Snyk Blog","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"},{"credibility":2,"name":"140+ Mastra npm Packages Compromised — Socket","type":"research","url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"credibility":1,"name":"Mastra GitHub Issue #18061 — Official Incident Report","type":"official","url":"https://github.com/mastra-ai/mastra/issues/18061"}]}],"sources_used":[{"credibility":2,"name":"Mastra npm Supply Chain Attack: 140+ Packages Backdoored via easy-day-js Typosquat — StepSecurity","type":"research","url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"},{"credibility":2,"name":"easy-day-js Supply Chain Attack Hits Mastra AI in npm — OX Security","type":"research","url":"https://www.ox.security/blog/easy-day-js-supply-chain-attack-hits-mastra-ai-in-npm/"},{"credibility":2,"name":"140+ Mastra npm Packages Compromised in Coordinated Supply Chain Attack — Socket","type":"research","url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"credibility":1,"name":"Mastra GitHub Issue #18061 — Official Incident Report","type":"official","url":"https://github.com/mastra-ai/mastra/issues/18061"},{"credibility":2,"name":"easy-day-js / EASY_DAY_JS_MASTRA_2026: Typosquatted Dependency Delivers Cross-Platform RAT — Phoenix Security","type":"research","url":"https://phoenix.security/easy-day-js-mastra-npm-supply-chain-typosquat-rat-2026/"},{"credibility":2,"name":"easy-day-js: Supply Chain Campaign Targets Mastra npm Packages — JFrog Security Research","type":"research","url":"https://research.jfrog.com/post/easy-day-js/"},{"credibility":2,"name":"Mastra npm Scope Takeover: A Forgotten Contributor Account Compromised the Entire Mastra npm Package Scope — Snyk","type":"research","url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"},{"credibility":2,"name":"144 Mastra npm Packages Compromised via Hijacked Contributor Account — The Hacker News","type":"news_article","url":"https://thehackernews.com/2026/06/144-mastra-npm-packages-compromised-via.html"},{"credibility":2,"name":"Mastra npm Supply Chain Attack Backdoors 144 Packages — AI Weekly","type":"news_article","url":"https://aiweekly.co/alerts/mastra-npm-supply-chain-attack-backdoors-144-packages"},{"credibility":2,"name":"Mastra npm Scope Takeover: 140+ Packages Compromised via easy-day-js Dropper — Mend.io","type":"research","url":"https://www.mend.io/blog/mastra-npm-scope-takeover-easy-day-js/"}],"summary":"On June 16–17, 2026, attackers published a typosquatted npm package named easy-day-js mimicking the legitimate dayjs date library, then used a hijacked former-contributor npm account (ehindero) to inject it as a dependency across 141–144 packages in the @mastra organization within an 88-minute window. The malicious postinstall payload functioned as a cross-platform remote access trojan (RAT) and infostealer, exfiltrating cryptocurrency wallet credentials, browser history, and developer secrets before self-deleting, with affected packages carrying a combined weekly download count exceeding 1.1 million.","timeline":[{"date":"2026-05-29","event":"An identical loader to the easy-day-js dropper was detected on public malware sandboxes, approximately 19 days before the Mastra attack, indicating prior toolkit testing or use.","source":"JFrog Security Research","source_url":"https://research.jfrog.com/post/easy-day-js/"},{"date":"2026-06-16","event":"npm account sergey2016 published easy-day-js@1.11.21 at 07:05 UTC — a clean, fully functional copy of the legitimate dayjs library with no malicious code, establishing a credible package history.","source":"StepSecurity / JFrog","source_url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"},{"date":"2026-06-17","event":"easy-day-js@1.11.22 published at 01:01 UTC by sergey2016 with obfuscated malicious postinstall dropper (setup.cjs). TLS verification disabled; C2 download from 23.254.164.92:8000.","source":"StepSecurity / Socket","source_url":"https://www.stepsecurity.io/blog/mastra-npm-packages-compromised-using-easy-day-js"},{"date":"2026-06-17","event":"Beginning at 01:12 UTC, compromised ehindero account mass-published 141–144 trojanized @mastra packages over 88 minutes (through approximately 02:39 UTC), each listing easy-day-js@^1.11.21 as a dependency.","source":"Socket / StepSecurity","source_url":"https://socket.dev/blog/mastra-npm-packages-compromised"},{"date":"2026-06-17","event":"Mastra team became aware of the attack at approximately 8:45 PM PT (June 16 US time) and contacted npm and Socket Security. Began unpublishing compromised packages.","source":"Mastra GitHub Issue #18061","source_url":"https://github.com/mastra-ai/mastra/issues/18061"},{"date":"2026-06-17","event":"By 11:57 PM PT: 110 malicious packages unpublished; 6 packages deprecated (npm prevented full unpublishing). Safe versions published via PR #18056 around 1:00 AM PT. MFA token bypass vulnerability removed.","source":"Mastra GitHub Issue #18061","source_url":"https://github.com/mastra-ai/mastra/issues/18061"},{"date":"2026-06-17","event":"Compromised maintainer confirmed as an active Mastra employee whose account was hijacked via social phishing through a fraudulent LinkedIn message. Attacker had changed the ehindero account email to ehindero2016@tutamail.com.","source":"Mastra GitHub Issue #18061 / Snyk","source_url":"https://snyk.io/blog/a-forgotten-contributor-account-compromised-the-entire-mastra-npm-package-scope/"},{"date":"2026-06-17","event":"Multiple security firms (StepSecurity, Socket, OX Security, JFrog, Snyk, Phoenix Security) published public technical analyses of the attack. JFrog flagged all compromised versions within 24 hours of detection.","source":"Multiple security research firms","source_url":"https://research.jfrog.com/post/easy-day-js/"}]},"v":1}
    Verify offline (run on your own machine)
    python -m src.verify_decision 1095e082-911e-41a5-98ce-430a506234bf
How verification works. The “Row integrity” check above is computed in your browser — your machine recomputes the SHA-256 of the canonical bytes and compares against the stored hash. No avoid.net server can fake that check. The “full verify” link goes one level deeper: your browser fetches the on-chain transaction from a Solana RPC node and confirms the same hash is in the memo. If you don’t want to trust either avoid.net or the public RPC, run the CLI verifier on your own machine — python -m src.verify_decision <event_id>.