GMO Flatt Security Blog

GMO Flatt Security株式会社の公式ブログです。プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

GMO Flatt Security株式会社の公式ブログです。
プロダクト開発やプロダクトセキュリティに関する技術的な知見・トレンドを伝える記事を発信しています。

mastra ソフトウェアサプライチェーン攻撃の概要と対応指針

2026年6月17日、mastra および @mastra/* の複数パッケージの改ざん(ソフトウェアサプライチェーン攻撃)が発生しました。悪性の依存パッケージ easy-day-js が注入されています。

easy-day-jspostinstall フックにより C2 サーバからマルウェアペイロードを取得・実行する Stager として動作します。 ペイロードはマルチプラットフォーム対応の RAT で、(1) ホスト情報の窃取、(2) OS レベルの永続化、(3) C2 への情報送信とリモートコマンド実行を行います。

本記事は、弊社が Takumi Guard の解析基盤をベースに観測&分析した情報を踏まえ、日本の Mastra コミュニティに向けて、影響と対策を中心に整理するものです。

TL;DR - 対応指針

  • 2026年6月16日以降に mastra 及び @mastra/* パッケージをインストールした場合、当該端末や CI にマルウェア感染の可能性があります。@mastra/coremastracreate-mastra を含む 141 パッケージ超が侵害されています。
  • 影響を受けた可能性がある場合は、以下を実施してください:
    • 感染端末内に存在するシークレット(APIキー、クラウドキー、LLM APIキー)の停止・ローテーション
    • 当該パッケージのアンインストール、または侵害前バージョンへのダウングレード
    • 永続化機構の確認と除去(詳細は「対応指針」セクションを参照)

はじめに

本記事の目的は事態の把握と対応の促進であり、違法行為への加担・助長を意図するものではありません。また速報性を優先しております為、記述の一部には不正確な情報が含まれている可能性があります。予めご容赦ください。

タイムライン

日時 (JST) イベント
6月16日 16:05 npm アカウント sergey2016sergey2016@tutamail.com)が easy-day-js@1.11.21 を公開。悪性コードは含まれていない(クリーンな dayjs のコピー)
6月17日 10:01 同アカウントが easy-day-js@1.11.22 を公開。postinstall フックと難読化された setup.cjs が追加される
6月17日 10:12〜11:36 npm アカウント ehinderoehindero2016@tutamail.com)が @mastra スコープの 141 パッケージを一括で再 publish。ライブラリコード自体は無改変で、package.json"easy-day-js": "^1.11.21" を追加する変更のみ
6月17日 10:39 mastra-ai/mastra#18045 で侵害が報告される
6月17日 15:50 頃 npm が悪性バージョンを削除したとみられる(easy-day-js レジストリの modified タイムスタンプに基づく推定)

侵害の仕組み

1. 初期侵入(推定):npm アカウントの乗っ取り

Mastra パッケージ群の侵害は、漏洩した npm トークンあるいはメンテナアカウントの乗っ取りによるものと推察されます。今回は Actions などを通さず、直接 npm レジストリ内のパッケージが変更されています。

侵害に用いられたのは、npm アカウント ehindero です。同アカウントは、実在する元 Mastra コントリビュータのアカウントと見られます。2024年11月〜2025年2月にかけて、@mastra/core の alpha 版(0.1.27-alpha.00.2.0-alpha.87)を 15 バージョン publish した正規の活動実績があるためです。

メンテナンス中に利用されていたメールアドレスは gmail.com ドメインのアドレスでした。一方、攻撃時(2026年6月17日)の publish は同じアカウント名ですが、メールアドレスが @tutamail.com ドメインのアドレスに変更されています。ここからも、攻撃者は元コントリビュータのアカウントを乗っ取ったと推察されます。

2. 依存関係の汚染

攻撃者の @mastra/* パッケージの改ざん内容はいたってシンプルで、package.json に 以下の依存を追加するものです。ライブラリコード(dist/)は改変していません。

"dependencies": {
  "easy-day-js": "^1.11.21",
  ...
}

easy-day-js は正規パッケージ dayjs のコピーで、npm アカウント sergey2016 が前日に公開したものです。2 バージョンが存在し、この分離が攻撃の仕掛けです。

  • 1.11.21:クリーンな dayjs コピー。install フックなし
  • 1.11.22postinstall フックを追加。setup.cjs(マルウェアローダ)を実行する

@mastra/* パッケージは ^1.11.21 に依存しています。1.11.22 はこの caret range を満たすため、npm install1.11.22 に解決します。1.11.21 を監査しても無害なコードしか見当たりません。ペイロードは npm が実際にインストールする 1.11.22 の側に載っています。おそらく検知回避のための小細工だと思われます。

3. ドロッパ setup.cjs の実行(Stage 1)

開発者が汚染済のパッケージをインストールすると、easy-day-js パッケージ内の postinstall フック経由で、setup.cjs が実行されます。

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

setup.cjs は難読化されていますが、およそ以下のような内容です:

  1. TLS 検証を無効化する(NODE_TLS_REJECT_UNAUTHORIZED = '0')。C2 が自己署名証明書を使っているため
  2. https://23[.]254[.]164[.]92:8000/update/49890878 から第二段ペイロードをダウンロードする。ペイロードをパッケージに同梱せずレジストリの外に置くことで、easy-day-js のスキャンでは日付ライブラリしか見つからない状態にしている
  3. ランダムなファイル名({12バイトの乱数hex}.js)でホームディレクトリに書き込み、detached プロセスとしてバックグラウンド実行する。C2 アドレス 23.254.164[.]123:443 を引数として渡す
  4. setup.cjs 自身を削除する(fs.rmSync(__filename, { force: true })

余談ですが:5/19/2026, 4:14:30 PM 頃に公開された @iconifi/react@4.1.1 等にも、同一構造の setup.cjs が同梱されていることを確認しています。同じ C2 アドレスとキャンペーン ID /49890878 を共有しており、同一の攻撃者によるキャンペーンの一部とみられます。

4. RAT の実行(Stage 2)

setup.cjs を経由してダウンロードされ、実行されるのは、所謂 RAT(遠隔操作型のマルウェア)です。本RATの挙動は分析中ですが、少なくとも、以下パスを利用した永続化が行われることは確認できています:

  • ~/.config/systemd/user/nvmconf.service
  • ~/.config/systemd/nvmconf/protocal.cjs

対応指針

以下は公開情報を踏まえた参考情報であり、記録として示すものです。正確性・網羅性を保証するものではなく、本指針に基づく対応の結果について筆者は一切の責任を負いません。実際の対応は各組織の判断に基づいて行ってください。

影響確認

package-lock.json または node_modules/easy-day-js が存在するか確認してください。 ~/.pkg_history または ~/.pkg_logsに関する操作ログの確認によっても確認できる可能性があります(が、通常これらのファイルは削除されるはずであり、痕跡としては残らないものと思料します)。

# 依存の確認
grep -r "easy-day-js" package-lock.json node_modules/*/package.json 2>/dev/null

# 永続化の確認(Linux)
ls -la ~/.config/systemd/user/nvmconf.service 2>/dev/null
ls -la ~/.config/systemd/nvmconf/protocal.cjs 2>/dev/null
ls -la ~/.config/NodePackages/config.json 2>/dev/null
systemctl --user status nvmconf 2>/dev/null

# 永続化の確認(macOS/Windows に於いては分析中につき、割愛)

# ドロッパの痕跡
ls -la ~/.pkg_history ~/.pkg_logs 2>/dev/null

除去

感染したパッケージをアンインストールするか、侵害前のバージョンに切り替えてください。 そのうえで、永続化機構の削除を行ってください。

# Linux: systemd service の停止と削除
systemctl --user stop nvmconf 2>/dev/null
systemctl --user disable nvmconf 2>/dev/null
rm -f ~/.config/systemd/user/nvmconf.service
rm -rf ~/.config/systemd/nvmconf/
rm -rf ~/.config/NodePackages/
systemctl --user daemon-reload

# macOS, Windows に関しては分析中につき、割愛

# 共通: ドロッパの痕跡削除
rm -f ~/.pkg_history ~/.pkg_logs

クレデンシャルのローテーション

RAT がホスト情報を収集して C2 に送信するように見受けられます。ワーストケースを想定して、感染端末からアクセス可能だった全てのシークレット(クラウドキー、LLM APIキー等)に関して、ローテーションを推奨します。

推奨:自衛手段の整備

3〜4月の Trivy・LiteLLM・Telnyx・axios・@bitwarden/cli、そして今回の Mini Shai-Hulud と、主要パッケージの侵害が連続して発生しています。対策の方向性は前回までと同じです。

Lifecycle script の無効化

CI/CD では以下を標準ポリシーにしてください。今回の npm 側 5 パッケージは、これだけで npm install 時の発火を止められます。

npm ci --ignore-scripts

ただし PyPI の lightning のように __init__.py 注入型は import 時に発火するため、lifecycle script の無効化では止まりません。後述の検疫期間とレジストリ側ブロックで補完してください。

Dependency Cooldown の設定(min-release-age

npm v11 以降では .npmrcmin-release-age を設定することで、公開から一定期間が経過していないバージョンのインストールを抑止できます。今回の悪性バージョンはいずれも数時間〜1 日でテイクダウン済であり、検疫期間を入れていた環境はインストールに至っていません。7 日推奨、急ぐ場合でも 3 日は確保してください。

# .npmrc
min-release-age=7

PyPI 側にも pip の --exclude-neweruv--exclude-newer 相当の指定で同等の抑止が可能です。

Provenance attestation の検証

今回の侵害では、正規版には SLSA Provenance が付与されていたのに対し、悪性版では脱落しています。

Mastra は正規リリースを CI(GitHub Actions)経由の npm trusted publisher フローで公開しており、各バージョンには SLSA Provenance attestation(Sigstore 署名付き)が付与されています。攻撃者は個人トークンで publish したため、悪性バージョンには Provenance が付いていません

隣接するバージョンを比較すると明確です:

@mastra/core@1.42.0   publisher: npm-oidc-no-reply@github.com   provenance: あり   easy-day-js: なし
@mastra/core@1.42.1   publisher: ehindero2016@tutamail.com       provenance: なし   easy-day-js: あり

npm audit signaturestrustPolicy: no-downgrade の設定により、今回の問題は防ぐことができたものと思料します。

悪意のある依存をブロック(Takumi Guard)

弊社(GMO Flatt Security)から、セキュアなレジストリプロキシ Takumi Guard の npm エンドポイント をリリースしています。

Takumi Guard は npm(レジストリ)との間に位置するセキュリティプロキシで、悪意あるパッケージがブロックされます。 弊社で全ての新規パッケージを検査し、ブロックリストを構築しています。 PyPI / RubyGems にも対応済です。導入は registry URL の変更のみで完了し、無料で利用可能です。

# npm
npm config set registry https://npm.flatt.tech/

# yarn v1
yarn config set registry https://npm.flatt.tech

# yarn v2+
yarn config set npmRegistryServer https://npm.flatt.tech

# pnpm
pnpm config set registry https://npm.flatt.tech/

仮にある時点でパッケージがマルウェアと判定できずブロックできなかった場合も、後日の通知を行う仕組みもあります(本機能も無料です)。 通知のためにはメールアドレス登録が必要となりますので、下記ページよりご登録ください。

複数端末の一括セットアップや管理者への通知など、法人向け管理機能(有償)も提供しています。 ご興味のある方はお問い合わせください。

IoCs

アカウント

種別
npm アカウント(@mastra publish) ehindero
npm アカウント(easy-day-js publish) sergey2016

ハッシュ(SHA-256)

ファイル SHA-256
easy-day-js@1.11.22 / setup.cjs b122a9873bedf145ae2a7fd024b5f309007dbb025149f4dc4ac3f7e4f32a36a4
easy-day-js@1.11.22 / package.json c38954e85bf5433e61e7c8f4230336695624ae88b6953afabf7bf817aa91b638

ネットワーク

種別 備考
ドロッパ C2 23.254.164[.]92:8000 /update/49890878、User-Agent ゲート付き
RAT C2 23.254.164[.]123:443 HTTPS POST ビーコン(分析時点で稼働中)
キャンペーン ID /49890878 ドロッパ・RAT 共通

永続化パス

OS パス 備考
Linux ~/.config/systemd/user/nvmconf.service systemd user service
Linux ~/.config/systemd/nvmconf/protocal.cjs ペイロード本体
Linux ~/.config/NodePackages/config.json RAT 設定ファイル
共通 ~/.pkg_history インストールパスの記録
共通 ~/.pkg_logs マーカーファイル

プロセス実行痕

コマンド 備考
node setup.cjs --no-warnings Stage 1 ドロッパ
node {random_hex}.js {C2_addr} Stage 2 RAT(ファイル名は crypto.randomBytes(12) で毎回異なる)
systemctl --user daemon-reload Linux 永続化