Mastra npm Packages Compromised: The easy-day-js Typosquat, IOCs, and First-Hour Response

June 17, 2026
June 17, 2026

0 min read

Vulnerabilities
Mastra npm Packages Compromised: easy-day-js Supply Chain Attack

On June 17, 2026, an attacker with access to the @mastra npm organization published malicious new versions of 13 packages across the Mastra AI framework ecosystem. Each compromised package quietly added easy-day-js, a freshly created typosquat of the popular dayjs date library, as a production dependency. That package carried a postinstall hook that ran an obfuscated dropper, pulled a second-stage payload from attacker infrastructure, and then deleted itself to erase the evidence. The compromise was documented by StepSecurity, and the Mastra maintainers are tracking it in issue #18045.

This is a textbook npm supply chain attack, executed against the dependency tree of an AI agent framework. The mechanics are worth understanding in detail, because they explain why a dependency scan tells you the package is present but not whether the dropper actually ran in your environment. This post covers what happened, the full timeline, what the dropper does, the indicators of compromise, a first-hour runbook, and why answering the real question requires runtime evidence.

Attack Summary

FieldValue
Disclosure dateJune 17, 2026
Affected ecosystem@mastra npm organization (AI agent framework)
Compromised packages13 @mastra/* packages republished with a malicious dependency
Malicious dependencyeasy-day-js (typosquat of dayjs)
Malicious version[email protected] (bait version 1.11.21 published first)
Execution vectorpostinstall hook running an obfuscated setup.cjs dropper
Stage-2 downloadhttps://23.254.164.92:8000/update/49890878
Stage-2 beacon23.254.164.123:443
Attacker npm accountsergey2016 (published the typosquat)
BehaviorDisables TLS validation, beacons install path, runs detached payload, self-deletes
Likely objectiveHarvesting LLM, cloud, and VCS credentials from developer and CI environments

Mastra Sits Exactly Where the High-Value Secrets Live

Mastra is an open-source TypeScript framework for building AI agents, workflows, and RAG pipelines. Its packages integrate LLM providers like OpenAI, Anthropic, and Google, manage persistent memory, implement Model Context Protocol servers, and deploy AI workloads to cloud providers. In practice that means @mastra packages are installed in three places that matter to an attacker: developer laptops, CI/CD pipelines, and production AI services.

Those are exactly the environments that hold LLM API keys, cloud provider tokens, and database credentials. A compromise of the framework's dependency tree is not a compromise of one application. It is a foothold across every team that runs a fresh install while the malicious versions were live.

How the Attack Unfolded

The campaign ran in two phases. The first built a credible decoy. The second weaponized it across the organization in 36 minutes.

Phase 1: A typosquat built to look real (June 16)

At 07:05 UTC on June 16, the npm account sergey2016 published [email protected], a clean copy of the legitimate dayjs library with no postinstall hook and no malicious files. The metadata was crafted to pass a casual review: it copied dayjs's author field (iamkun), homepage (https://day.js.org), repository URL, keywords, and even matched the real [email protected] version lineage. This was bait, and it was the version referenced by the @mastra packages.

Phase 2: Organization compromise and mass publish (June 17)

At 01:01 UTC on June 17, the attacker published [email protected], identical to the bait release except for the addition of setup.cjs and its postinstall hook. Eleven minutes later, using compromised @mastra organization credentials, they began republishing @mastra packages with "easy-day-js": "^1.11.21" added as a production dependency. Because the caret range ^1.11.21 resolves to the latest matching version at install time, every fresh npm install pulled the malicious 1.11.22. Thirteen packages went out in 36 minutes:

Time (UTC)Package
01:01[email protected] (malicious dropper)
01:12@mastra/[email protected]
01:15@mastra/[email protected]
01:16@mastra/[email protected]
01:17@mastra/[email protected]
01:19@mastra/[email protected]
01:25@mastra/[email protected]
01:25@mastra/[email protected]
01:26@mastra/[email protected]
01:29@mastra/[email protected]
01:30@mastra/[email protected]
01:30@mastra/[email protected]
01:41@mastra/[email protected]
01:48@mastra/[email protected]

The Dropper Disables Trust, Beacons, Runs, and Erases Itself

When npm installs any infected @mastra package, it resolves easy-day-js to 1.11.22 and runs its postinstall hook:

"postinstall": "node setup.cjs --no-warnings"

The --no-warnings flag suppresses the Node.js deprecation and experimental notices that might otherwise catch a developer's eye. The setup.cjs file is 4,572 bytes and heavily obfuscated using a custom string-encoding scheme: a shuffled-alphabet Base64 variant backed by a 40-element string array that must be rotated 34 positions before the integrity check passes. Stripped of the obfuscation, the logic is compact and deliberate:

  • It sets NODE_TLS_REJECT_UNAUTHORIZED='0', disabling TLS certificate validation so the attacker can serve the next stage over a self-signed certificate on a raw IP.
  • It writes the install path and an XOR-encoded package marker into .pkg_history and .pkg_logs in the system temp directory, a beacon recording where it landed.
  • It fetches the second stage from https://23.254.164.92:8000/update/49890878 and writes it to a random-named .js file in the temp directory.
  • It spawns that file with node, passing 23.254.164.123:443 as an argument, using detached: true, stdio: 'ignore', and .unref() so the process outlives the install and produces no output.
  • It deletes setup.cjs with fs.rmSync(__filename, { force: true }), removing the first-stage evidence from disk.

What the Second Stage Likely Targets

The second-stage payload is not embedded in the tarball. It is pulled at runtime from attacker infrastructure, so static analysis of the package never sees it. Based on the install context and the infrastructure pattern (the same /24 network and conventional HTTPS port 443 for the beacon), the payload almost certainly harvests environment variables and exfiltrates them to 23.254.164.123:443.

In a Mastra environment, those variables are the crown jewels: LLM keys such as ANTHROPIC_API_KEY and OPENAI_API_KEY, cloud credentials such as AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, and version-control tokens such as GITHUB_TOKEN and NPM_TOKEN. A stolen NPM_TOKEN is how a single compromise becomes the next one.

Indicators of Compromise

Treat any environment that ran npm install for an affected package between 01:01 UTC and the time the versions were pulled as potentially exposed. Hunt for the following.

CategoryIndicator
Dependencyeasy-day-js at any version in a lockfile or node_modules, especially 1.11.22 and 1.11.21
PackagesThe 13 @mastra/* versions listed above in any dependency tree
Network (download)Connections to 23.254.164.92:8000, path /update/49890878
Network (beacon)Connections to 23.254.164.123:443
Filesystem.pkg_history and .pkg_logs in the system temp directory; random-named .js files in temp
ProcessA detached node process launched from a temp-directory script during or just after npm install
ManifestA postinstall hook running node setup.cjs --no-warnings
Publishernpm account sergey2016 as the publisher of easy-day-js

Immediate Response: The First-Hour Runbook

The dropper runs at install time and the second stage runs detached, so the priority is to assume credential exposure and rotate, not just to remove the package.

  1. Pin away from the malicious versions. Remove easy-day-js entirely and pin affected @mastra packages to known-good releases published before 01:01 UTC on June 17, 2026. Reinstall from a clean lockfile.
  2. Find every instance. Run npm ls easy-day-js and audit lockfiles across repos and CI. The dependency was transitive through @mastra, so it will not appear in your top-level package.json.
  3. Rotate exposed secrets. Assume any credential present in an environment that ran the install is compromised. Rotate LLM API keys, cloud tokens, database credentials, GITHUB_TOKEN, and NPM_TOKEN.
  4. Block the infrastructure. Block outbound traffic to 23.254.164.92 and 23.254.164.123 and alert on any historical connections.
  5. Check for execution. Search process and network telemetry for the detached node process and the C2 callouts. Presence of the package and proof that the dropper ran are different questions.
  6. Inspect CI runners. Ephemeral build agents that ran a fresh install are high priority, because their tokens are often broadly scoped and rarely rotated.

Finding the Package Is Not the Same as Knowing You Were Hit

A dependency scanner tells you easy-day-js is in your tree. It cannot tell you whether the postinstall hook executed, whether the second stage was fetched, or whether your secrets left the building. For an install-time dropper, that gap is the entire incident. Severity without execution context is noise, and "the package is present" is a starting point, not an answer.

That gap between presence and execution is where Kodem operates.

  • Kodem's SCA surfaces every copy of easy-day-js and every affected @mastra version across direct and transitive dependency trees, so inventory takes minutes rather than a day of grepping lockfiles.
  • Runtime Intelligence, Kodem's patented foundational layer, confirms what actually executed: whether the install ran, whether the dropper spawned a process, and whether outbound connections to the C2 infrastructure occurred. That is the difference between "we have the package" and "we were hit."
  • Kodem's Application Detection and Response layer catches the behavior this attack depends on: an unexpected subprocess spawned during install and a callout to fresh infrastructure, detected at the moment it happens, without waiting for a signature.
  • Kai folds that evidence into a prioritized, ready-to-action response, so the team spends the first hour rotating the right credentials instead of guessing which environments were exposed.

Hardening Against the Next Postinstall Dropper

Install-time execution is the recurring pattern in npm supply chain attacks. Shrinking its blast radius is a configuration problem you can solve before the next one lands.

  1. Disable install scripts by default in CI with npm install --ignore-scripts, and allowlist the few packages that genuinely need them.
  2. Adopt an install cooldown so brand-new package versions cannot be pulled into builds within hours of publication.
  3. Scope CI and npm tokens tightly and rotate them on a schedule, so a single harvested token does not unlock the whole pipeline.
  4. Pin dependencies with a committed lockfile and review lockfile diffs, where a surprise new transitive dependency like easy-day-js would have been visible.
  5. Maintain a current SBOM so a newly disclosed package can be located across every service in minutes.
  6. Monitor runtime behavior on developer machines and build agents for unexpected subprocess execution and outbound connections to new infrastructure.

What This Signals for AI Framework Supply Chains

AI agent frameworks have become high-value supply chain targets for a simple reason: they live next to the most valuable secrets in a modern stack. The environments that run Mastra, LangChain, and similar tooling hold LLM keys, cloud credentials, and database access, and they run installs constantly as teams iterate on agents.

This campaign also shows how little time defenders get. The decoy was seeded a day in advance, and the weaponized publish window was 36 minutes. Detection that depends on a CVE being assigned, an advisory being written, and a scanner rule being updated is measured in days. The malicious behavior, an install-time process spawning a child and calling out to fresh infrastructure, is observable the moment it happens. Expect more compromises of AI framework dependency trees, and expect the useful question to keep shifting from "is the package present" to "did it execute here."

Frequently Asked Questions

  1. What happened in the Mastra npm compromise? On June 17, 2026, an attacker with access to the @mastra npm organization republished 13 packages, each adding easy-day-js, a typosquat of dayjs, as a production dependency. That package ran a postinstall dropper that fetched and executed a second-stage payload, then deleted itself.
  2. Which packages are affected? Thirteen @mastra/* packages including @mastra/[email protected], @mastra/[email protected], @mastra/[email protected], @mastra/[email protected], and @mastra/[email protected], plus the malicious [email protected]. The full list with versions and timestamps is in the timeline above.
  3. How do I know if I am affected? Run npm ls easy-day-js and check whether any affected @mastra version is in your lockfiles or node_modules. Then check network telemetry for connections to 23.254.164.92 or 23.254.164.123, and process telemetry for a detached node process launched from the temp directory.
  4. What does the malware steal? The second stage was not retrieved during static analysis, but the install context and infrastructure strongly indicate it harvests environment variables, including LLM API keys, cloud credentials, and VCS tokens, and exfiltrates them to 23.254.164.123:443.
  5. I removed the package. Am I safe? Removing the package stops future installs but does not undo a dropper that already ran. If any affected version was installed, assume the secrets in that environment were exposed and rotate them.
  6. Why does a dependency scan not settle this? A scan confirms the package is present. It cannot confirm the postinstall hook executed or that data left the environment. That requires runtime evidence of process execution and network activity, which is the question that actually determines your exposure.
  7. How can I prevent this class of attack? Disable install scripts in CI by default, adopt a publish cooldown for new versions, scope and rotate tokens, review lockfile diffs, and monitor build agents for unexpected subprocess and network behavior.

The Bottom Line

The Mastra compromise is not exotic. A convincing typosquat, a compromised publishing account, a caret version range, and a postinstall hook were enough to turn a routine install into credential theft across developer machines and CI. The fix is straightforward: remove easy-day-js, pin to clean versions, and rotate exposed secrets.

The harder problem is knowing where the dropper actually ran and what it touched. That is a runtime question, not a scanner question, and it is the part Kodem connects from code to runtime. SCA finds every affected package in the dependency graph, Runtime Intelligence proves whether the malicious code executed, and Kai turns that into a prioritized response while the tokens are still being rotated.

References

  1. StepSecurity. June 17, 2026. @mastra npm Packages Compromised. stepsecurity.io.
  2. Mastra. Issue #18045: compromised package versions. github.com/mastra-ai/mastra.
  3. Kodem Security. From Reachability to Reality: Proving Vulnerable Code Was Executed and Exploited in Production. Kodem Security.
  4. Kodem Security. Tanstack and OpenAI Supply Chain Attack: Mini Shai-Hulud IOCs and First-Hour Response Runbook. Kodem Security.
  5. Kodem Security. Know which packages are actually exploitable in your environment. Kodem Security.
  6. Kodem Security. Stop attacks at the first malicious action. Kodem Security.
Table of contents

Related blogs

CVE-2026-9277 shell-quote Command Injection

CVE-2026-9277 is a shell-quote command injection flaw in npm versions 1.1.0 through 1.8.3. See how the quote() bypass works, what to hunt, and the 1.8.4 fix.

June 12, 2026

9

TanStack OpenAI Supply Chain Attack: Mini Shai-Hulud, IOCs, and First-Hour Response Runbook

The TanStack OpenAI supply chain attack delivered Mini Shai-Hulud through trusted npm publishing. Get the IOCs, affected packages, and first-hour runbook.

June 5, 2026

13

Inside the TeamPCP Supply Chain Campaign: From Trivy to LiteLLM to the Checkmarx Jenkins Plugin

TeamPCP backdoored the Checkmarx Jenkins AST plugin. Get the affected versions, IOCs, and the first-hour CI/CD supply chain runbook.

May 14, 2026

15

Stop the waste.
Protect your environment with Kodem.

Get a personalized demo
Get a personalized demo

A Primer on Runtime Intelligence

See how Kodem's cutting-edge sensor technology revolutionizes application monitoring at the kernel level.

5.1k
Applications covered
1.1m
False positives eliminated
4.8k
Triage hours reduced

Platform Overview Video

Watch our short platform overview video to see how Kodem discovers real security risks in your code at runtime.

5.1k
Applications covered
1.1m
False positives eliminated
4.8k
Triage hours reduced

The State of the Application Security Workflow

This report aims to equip readers with actionable insights that can help future-proof their security programs. Kodem, the publisher of this report, purpose built a platform that bridges these gaps by unifying shift-left strategies with runtime monitoring and protection.

3D book mockup of Kodem's State of the Application Security Workflow 2025 report

Get real-time insights across the full stack…code, containers, OS, and memory

Watch how Kodem’s runtime security platform detects and blocks attacks before they cause damage. No guesswork. Just precise, automated protection.

Kodem issues list with a magnified view of insight icons: runtime, ingress, and exploitability
Combined author
Kodem Security Research Team
Publish date

0 min read

Vulnerabilities