npm大規模サプライチェーン攻撃を解剖する — TanStack/Mistral AI含む172パッケージ侵害の手口と防御策
はじめに
2026年5月11日、npm エコシステムを震撼させる大規模なサプライチェーン攻撃が発生した。被害は 172パッケージ・404の悪意あるバージョン に及び、TanStack、Mistral AI、UiPath、OpenSearch といった著名プロジェクトが軒並み巻き込まれた。本記事では TanStack の公式ポストモーテムと SafeDep の調査レポートをもとに、攻撃者がどのように複数のセキュリティ境界を突破したのか、その手口と検知・防御の教訓を整理する。npm/PyPI を利用するすべてのエンジニアにとって、自分のCI/CD やパッケージ管理戦略を見直す重要な契機となる事件だ。
何が起きたのか — 被害規模と侵害された主要プロジェクト
今回の攻撃は単一の脆弱性ではなく、npm と PyPI の両方を横断する組織的なキャンペーンだった。SafeDep の集計によれば被害は以下の通り。
- TanStack エコシステム: 42パッケージ・84バージョン(@tanstack/router 系。query/table/form/virtual/store は無傷)
- Mistral AI: npm 3パッケージ+PyPI 2パッケージ(合計9バージョン)
- UiPath: 65パッケージ・65バージョン(RPA関連)
- OpenSearch: 公式 JavaScript クライアント(週次1.3Mダウンロード)
- Guardrails AI: PyPI 上のバリデーションフレームワーク
特筆すべきは攻撃が「個別の人気パッケージ」ではなく「組織のscope全体」を一気に侵害している点だ。OpenSearch のように週百万単位でダウンロードされるパッケージが含まれているため、依存ツリーをたどると影響はさらに広範に及ぶ。TanStack のポストモーテムは、悪意ある84バージョンが 19:15〜19:26 のわずか11分間 で連続publishされていたことを示しており、自動化された攻撃であることが明らかだ。
検知は外部からだった。TanStack チームは StepSecurity の研究者 ashishkurmi が GitHub issue #7383 で公開した技術解析を通じて事態を把握している。npm publish 直後の内部アラートは機能していなかった。
攻撃メカニズム — pull_request_target からOIDCトークン窃取まで
TanStack のケースは、GitHub Actions と npm の trusted-publisher 連携を悪用した極めて巧妙な多段攻撃だった。ポストモーテムは「The chain only works because each vulnerability bridges the trust boundary the others assumed.」と表現している。3つの脆弱性が連鎖して初めて成立した攻撃で、それぞれは単独では致命的に見えなかった。
- pull_request_target ワークフローの濫用:
bundle-size.ymlが fork からのコード(untrusted)をゲートキーピングなしで実行していた。pull_request_targetは元リポジトリのシークレットにアクセスできるため、Actions のセキュリティで最も警戒すべきトリガーの一つだ。 - GitHub Actions キャッシュポイズニング: フォーク側のジョブが共有キャッシュキーに悪意あるバイナリを書き込み、後続の本番ワークフローがそれを「信頼できるキャッシュ」として復元する。
- OIDCトークンの抜き取り: ランナーメモリから OIDC 認証トークンを抽出し、npm の trusted-publisher 連携を直接悪用してパッケージを publish する。
別経路の PyPI 系は手口が異なり、__init__.py に短いドロッパーを追加して transformers.pyz という二次ペイロードを https://git-tanstack.com/transformers.pyz(タイポスクワッティングドメイン)から取得し、python3 で実行する仕組みだ。npm 側は preinstall フックまたは optionalDependencies が、汚染された GitHub コミットを指す形で発火する。@tanstack/setup を optional 依存として注入し、本物のリポジトリ内の汚染コミットを参照させる手法は特に発見しづらい。
ペイロードの動作 — 認証情報窃取と”Claude Code/VS Code”を狙う自己伝播
約2.3MBの難読化された router_init.js ペイロードは、典型的なクレデンシャル収集ツールキットの域を超えていた。標的になった認証情報は以下のように広範だ。
- AWS IAM クレデンシャルおよびインスタンスメタデータ
- GCP / Kubernetes / HashiCorp Vault トークン
- GitHub トークン(
ghp_*/gho_*/ghs_*) - npm publish トークン、GitHub Actions OIDC トークン
- SSH 鍵
そして最も恐ろしいのが 自己伝播メカニズム だ。窃取した GitHub トークンを用い、GraphQL API 経由で被害者のリポジトリに .claude/settings.json と .vscode/tasks.json を上書きコミットする。これは Claude Code や VS Code を利用する開発者が、汚染設定によってさらに別のリポジトリへ攻撃を拡散させる経路を作るものだ。AI コーディング支援ツールが普及した時代を狙い撃ちした攻撃設計と言える。
データ送出には伝統的な C2 サーバではなく Session メッセンジャー(onion routing) が使われており、filev2.getsession.org や seed{1,2,3}.getsession.org がエンドポイントだ。テイクダウンが極めて困難な経路を選んでいる点も、攻撃者の準備の周到さを示している。
エンジニアへの影響 — 今すぐやるべき防御策
この事件は「npm からインストールしたパッケージは安全」という暗黙の仮定を完全に崩した。実務でいま取り組むべき対策を整理する。
短期(今すぐ):
- 5月11日前後にインストール・ビルドしたシステムで
node_modulesを破棄し、ロックファイルベースで再構築する。@tanstack/router 系・OpenSearch クライアント・UiPath パッケージなど影響範囲のバージョンを使っていないかを確認する。 - AWS / GCP / GitHub / npm のトークンとシークレットをローテーションする。CI環境のシークレットも対象。
- 自社リポジトリの
.claude/settings.json/.vscode/tasks.jsonを git diff で確認し、覚えのない変更がないか調査する。
中期(運用に組み込む):
- GitHub Actions の
pull_request_targetを全リポジトリで監査し、repository_ownerガードか専用の最小権限ジョブに分離する。 - サードパーティ Actions を SHA ピン留め(
@v6.0.2ではなく@<commit-sha>)する。 - npm/PyPI で
npm install --ignore-scriptsをデフォルトにする、Renovate/Dependabot に provenance チェックを組み込むなど、preinstall 実行をブロックする層を入れる。 - 自社パッケージの publish イベント監視を CI/CD ログとは独立して構築し、外部研究者より早く気づける体制にする。
長期的には npm の trusted-publisher 連携や OIDC を使う際にも、manual approval gate を一段挟む運用が必要になる。TanStack のように7人のメンテナがいると、それは7個のクレデンシャル窃取攻撃面でもあるという認識が重要だ。
まとめ
今回のnpm/PyPI同時侵害は、攻撃者が「個別パッケージの脆弱性」から「組織scope全体を一気に侵害する自動化キャンペーン」へとシフトしたことを示す転換点だ。pull_request_target、Actions キャッシュ、OIDC トークンという3つの一見独立した境界が連鎖して破られた点、そして AI コーディング支援ツールの設定ファイルを自己伝播経路に利用した点は、今後の攻撃トレンドを予感させる。エンジニアとしては、依存パッケージの選定だけでなく CI/CD ワークフローのセキュリティ設計も「自分の責任範囲」として捉え直す必要がある。npm install の利便性の裏側で何が動いているかを意識する時代に、私たちは確実に入った。
今日のその他のニュース
Claude Code に「agent view」が登場: 複数の Claude Code エージェントを1画面で管理できる公式機能が AWS 経由でリリース。並行開発を多用する開発者にとって即試す価値あり。(GIGAZINE)
Firebase AI Logic / Phone Number Verification GA: Hybrid inference が Android で利用可能に、iOS 対応も5月中。Cloud Functions for Firebase が Dart を実験サポートし、フルスタック Dart が現実味を帯びてきた。(Firebase Blog)
Learning Software Architecture(matklad): rust-analyzer 作者によるアーキテクチャ学習論。実装と設計の往復をどう積み重ねるか、抽象化の罠をどう見抜くかが論じられている。(matklad blog)