
Over 140 popular Mastra npm Packages Hit by Supply Chain Attack
Aikido details a supply chain attack in which an attacker took over the entire @mastra npm scope, republishing 141 packages (including @mastra/core with 918K weekly downloads) to add a malicious dependency, easy-day-js, a dayjs clone. A staged clean-then-malicious version (1.11.21 → 1.11.22) exploited npm's caret resolution so the postinstall script setup.cjs fetched a second-stage payload from a C2 server, spawned it as a detached background process targeting 160+ browser crypto wallet extensions, and self-deleted to erase forensic evidence. Aikido notes the attack closely mirrors the earlier axios compromise (same Hostwinds infrastructure pattern, decoy-then-malicious staging, postinstall hook, self-deletion).
What it is
A supply-chain attack on the entire @mastra npm scope (a popular open-source AI agent framework), detected by Aikido on June 17th. An attacker republished 141 packages in a burst between 01:15–02:00 UTC, injecting a single malicious dependency into each. Named packages include @mastra/core (918K weekly downloads, republished as 1.42.1), mastra@1.13.1, and create-mastra@1.13.1.
How it works
The injected dependency is easy-day-js, a malicious clone of dayjs published from a separate attacker account a day earlier. The trick is version resolution: the compromised packages depend on ^1.11.21, and 1.11.21 was a clean copy of dayjs with no install hooks — so auditing the pinned version reveals nothing. The malicious 1.11.22 was published the next day, and npm's caret resolution silently pulls it in as latest.
1.11.22 adds a postinstall hook running an obfuscated setup.cjs. It:
- Fetches a second-stage payload from
23[.]254[.]164[.]92:8000 - Writes it to a randomly named
.jsfile in the OS temp dir - Spawns it fully detached (
stdio: ignore,windowsHide: true), passing23[.]254[.]164[.]123:443as an argument - Self-deletes to remove forensic traces
The second stage is a long-lived RAT that collects system info and targets 160+ browser crypto-wallet extensions (MetaMask, Keplr, Coinbase), establishes persistence disguised as node tooling on macOS/Windows/Linux, and phones home to 23[.]254[.]164[.]123:443.
flowchart TD
A["package depends on easy-day-js ^1.11.21"] --> B{npm caret resolution}
B -->|"pins 1.11.21 (clean decoy)"| C["audit finds nothing"]
B -->|"latest = 1.11.22"| D["postinstall runs setup.cjs"]
D --> E["fetch payload from :8000"]
E --> F["spawn detached RAT, self-delete"]
F --> G["target 160+ wallets, persist, C2 :443"]Preconditions / Affected
Any project installing an affected @mastra package (or easy-day-js) after the malicious 1.11.22 publish, where the postinstall hook is allowed to run. Because caret ranges resolve to latest, installs and CI builds that don't pin exact versions are exposed.
What to do
- Aikido users: check the central feed, filter on malware issues (surfaces as a 100/100 critical), and trigger a manual rescan — nightly rescan may not have run yet.
- Audit lockfiles and installed trees for
easy-day-js@1.11.22and the affected@mastraversions. - Block/monitor the network IOCs:
23[.]254[.]164[.]92:8000(first-stage payload download) and23[.]254[.]164[.]123:443(second-stage RAT callback). - The page suggests Aikido Safe Chain (open source), which intercepts
npm,npx,yarn,pnpm, andpnpxto check packages before install.
Caveats
The report attributes the compromise to "likely" a maintainer account or CI token takeover — the exact initial vector isn't confirmed. The affected-package list in the fetched text is truncated mid-scope (@mastra/i…), so treat the full 141-package set as larger than what's shown here.
Organisations named here
- easy-day-js
- Hostwinds
Technologies named here
- @mastra/core
- Aikido
- Aikido Device Protection
- mastra
- Aikido Safe Chain
- create-mastra
- Aikido Intel
- easy-day-js
- @mastra/acp
- @mastra/agent-browser
- @mastra/agent-builder
- @mastra/agentcore
- @mastra/agentfs
- @mastra/ai-sdk
- @mastra/arize
- @mastra/arthur
- @mastra/astra
- @mastra/auth
- @mastra/auth-auth0
- @mastra/auth-better-auth
- @mastra/auth-clerk
- @mastra/auth-cloud
- @mastra/auth-firebase
- @mastra/auth-okta
- @mastra/auth-studio
- @mastra/auth-supabase
- @mastra/auth-workos
- @mastra/azure
- @mastra/blaxel
- @mastra/braintrust
- @mastra/brightdata
- @mastra/browser-firecrawl
- @mastra/browser-viewer
- @mastra/chroma
- @mastra/claude
- @mastra/clickhouse
- @mastra/client-js
- @mastra/cloud
- @mastra/cloudflare
- @mastra/cloudflare-d1
- @mastra/codemod
- @mastra/convex
- @mastra/couchbase
- @mastra/cursor
- @mastra/dane
- @mastra/datadog
- @mastra/daytona
- @mastra/deployer
- @mastra/deployer-cloud
- @mastra/deployer-cloudflare
- @mastra/deployer-netlify
- @mastra/deployer-vercel
- @mastra/docker
- @mastra/dsql
- @mastra/duckdb
- @mastra/dynamodb
- @mastra/e2b
- @mastra/editor
- @mastra/elasticsearch
- @mastra/engine
- @mastra/evals
- @mastra/express
- @mastra/fastembed
- @mastra/fastify
- @mastra/files-sdk
- @mastra/gcs
- @mastra/github-signals
- @mastra/google-cloud-pubsub
- @mastra/google-drive
- @mastra/hono
- @mastra/inngest
- @mastra/koa
- @mastra/laminar
- @mastra/lance
- @mastra/langfuse
- @mastra/langsmith
- @mastra/libsql
- @mastra/loggers
- @mastra/longmemeval
- @mastra/mcp
- @mastra/mcp-docs-server
- @mastra/mcp-registry-registry
- @mastra/mem0
- @mastra/memory
- @mastra/modal
- @mastra/mongodb
- @mastra/mssql
- @mastra/mysql
- @mastra/nestjs
- @mastra/node-audio
- @mastra/node-speaker
- @mastra/observability
- @mastra/openai
- @mastra/opencode
- @mastra/opensearch
- @mastra/otel-bridge
- @mastra/otel-exporter
- @mastra/perplexity
- @mastra/pg
- @mastra/pinecone
- @mastra/playground-ui
- @mastra/posthog
- @mastra/qdrant
- @mastra/rag
- @mastra/railway
- @mastra/react
- @mastra/redis
- @mastra/redis-streams
- @mastra/s3
- @mastra/s3vectors
- @mastra/schema-compat
- @mastra/sentry
- @mastra/server
- @mastra/slack
- @mastra/spanner
- @mastra/speech-azure
- @mastra/speech-elevenlabs
- @mastra/speech-google
- @mastra/speech-ibm
- @mastra/speech-murf
- @mastra/speech-openai
- @mastra/speech-replicate
- @mastra/speech-speechify
- @mastra/stagehand
- @mastra/tavily
- @mastra/temporal
- @mastra/turbopuffer
- @mastra/twilio
- @mastra/upstash
- @mastra/vectorize
- @mastra/vercel
- @mastra/voice-aws-nova-sonic
- @mastra/voice-azure
- @mastra/voice-cloudflare
- @mastra/voice-deepgram
- @mastra/voice-elevenlabs
- @mastra/voice-gladia
- @mastra/voice-google
- @mastra/voice-google-gemini-live
- @mastra/voice-inworld
- @mastra/voice-modelslab
- @mastra/voice-murf
- @mastra/voice-openai
- @mastra/voice-openai-realtime
- @mastra/voice-playai
- @mastra/voice-sarvam
- @mastra/voice-speechify
- @mastra/voice-xai-realtime
- Browser-based crypto wallet extensions
- npm
- Aikido Security
- axios
Techniques named here
- npm scope takeover / supply chain attack
- Malicious dependency injection via clone package
- Clean decoy version followed by malicious update
- Dependency version pinning bypass via caret resolution
- Malicious postinstall script
- C2 payload retrieval
- Detached background process execution
- Self-deletion / anti-forensics
- Persistence via disguised process naming
- Crypto wallet targeting
Threat actors named here
- Unnamed attacker
- axios compromise attacker
Related in Supply Chain


