supply-chain security npm typosquat ai

Mastra npm packages were backdoored through an easy-day-js typosquat

A compromised @mastra publish added a dayjs-looking dependency across 140+ packages. Here's what happened, how to check exposure, and what to do next.

boring.tools team

boring.tools team

The team behind boring.tools.

4 min read
Mastra npm packages were backdoored through an easy-day-js typosquat

On June 17, 2026, a supply-chain attacker turned a single typo into a mass compromise of the Mastra AI framework ecosystem. According to StepSecurity’s incident write-up, the attacker compromised the @mastra npm organization and added easy-day-js — a package designed to look like the popular dayjs library — as a production dependency across more than 140 packages.

The important lesson is not just “watch for typosquats.” The attack combined a believable package name, semver range resolution, an install-time postinstall hook, and the trust developers place in AI tooling dependencies. That is exactly the kind of compromise a modern dependency inventory needs to make visible quickly.

What happened

The campaign started with a clean bait package. On June 16, StepSecurity says npm user sergey2016 published easy-day-js@1.11.21, a functional copy of dayjs metadata and versioning. It mirrored signals a reviewer might glance at — author metadata, repository URL, homepage, license, keywords, and the familiar 1.11.x version line.

The next day, at 01:01 UTC, the same account published easy-day-js@1.11.22 with a new setup.cjs file and a postinstall command:

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

Eleven minutes later, the attacker began republishing Mastra packages with "easy-day-js": "^1.11.21" added as a dependency. That range is the trick: even if 1.11.21 was clean when it was injected, a fresh install would resolve to the later malicious 1.11.22 version.

StepSecurity’s timeline says the first affected Mastra package was @mastra/schema-compat@1.2.12 at 01:12 UTC, followed by core packages such as @mastra/core@1.42.1, @mastra/memory@1.20.4, @mastra/server@2.1.1, and the top-level mastra@1.13.1. Over an 88-minute window, more than 140 packages were republished, with combined weekly downloads above 1.1 million.

StepSecurity also opened a disclosure issue in the Mastra repository, titled “Security: multiple @mastra npm packages compromised.” The issue is now closed, but it records the public disclosure path for the incident.

Why this matters for software supply chains

Mastra sits in a high-value part of the stack: AI agents, workflows, RAG pipelines, MCP integrations, cloud deployments, and LLM provider SDKs. Development and CI environments using those packages often contain exactly the credentials attackers want: OPENAI_API_KEY, ANTHROPIC_API_KEY, cloud access keys, database URLs, GITHUB_TOKEN, npm tokens, and deployment secrets.

The malicious package did not need to alter application code. It only needed to execute during installation. StepSecurity’s analysis says setup.cjs disabled TLS certificate validation, downloaded a second-stage payload from https://23.254.164.92:8000/update/49890878, wrote temporary marker files such as <tmpdir>/.pkg_history, and spawned the payload as a detached background process with 23.254.164.123:443 passed as the command-and-control address.

That makes this incident especially relevant to teams that still treat package install as a low-risk build step. npm install is code execution. If it runs on a developer workstation or CI runner with broad credentials, the blast radius can include source control, package publishing, cloud infrastructure, and downstream customers.

How to check whether you are affected

Start with your lockfiles, registry logs, and CI install logs for June 17 and after. You are looking for two things: compromised Mastra versions and the malicious transitive dependency.

Check for the typosquat directly:

grep -R "easy-day-js" package-lock.json pnpm-lock.yaml bun.lock yarn.lock 2>/dev/null

If you use npm, inspect resolved dependency trees in projects that depend on Mastra:

npm ls easy-day-js @mastra/core mastra

Then search build logs and endpoint telemetry for indicators from StepSecurity’s report:

  • npm package: easy-day-js@1.11.22
  • npm maintainer: sergey2016 / sergey2016@tutamail.com
  • install hook: node setup.cjs --no-warnings
  • stage-2 download: https://23.254.164.92:8000/update/49890878
  • C2 address: 23.254.164.123:443
  • temp files: <tmpdir>/.pkg_history, <tmpdir>/.pkg_logs, or a random <24-hex-chars>.js
  • runtime change: NODE_TLS_REJECT_UNAUTHORIZED=0

If easy-day-js was installed in a CI runner or developer machine, do not stop at deleting node_modules. Treat the environment as potentially compromised and rotate credentials that were available to the install process.

What to do next

First, pin and rebuild from known-good package versions. Remove easy-day-js from dependency graphs, refresh lockfiles, and make sure new installs cannot resolve the malicious version from cache or a proxy registry.

Second, rotate secrets exposed to the install environment. Prioritize npm publish tokens, GitHub tokens, cloud credentials, deployment keys, LLM API keys, and database credentials. If the install ran in CI, review workflow permissions and invalidate long-lived tokens that were present as environment variables.

Third, add runtime controls around dependency installation. A static dependency scanner can flag known bad packages after intelligence is published, but this attack’s most damaging step was a live outbound connection during postinstall. CI network egress policies, package-version cooldowns, and registry-level quarantine give you a chance to stop the payload before it leaves the runner.

Finally, make dependency provenance part of incident response. A fast answer to “which repos, branches, and machines pulled this package?” is the difference between targeted cleanup and organization-wide panic.


boring.tools helps teams inventory dependencies, generate SBOMs, and monitor repositories for supply-chain exposure. If you need to prove which projects were using a compromised package, start with an up-to-date SBOM and lockfile-backed dependency map.