世界を動かす技術を、日本語で。

TanStackのNPMパッケージが侵害されました

概要

  • TanStack/router の npm 最新リリースがセキュリティ侵害の被害
  • 2026年5月11日 に問題が報告
  • 自己拡散型サプライチェーン攻撃 の疑い
  • 詳細と調査状況は StepSecurity のブログで公開
  • 通知設定や操作には サインイン が必要

npm最新リリースのセキュリティ侵害について

  • TanStack/router のいくつかの npm最新リリース においてセキュリティ侵害が発生

  • 2026年5月11日、ユーザー ashishkurmi によって GitHub Issue #7383 で報告

  • 攻撃の詳細は 自己拡散型サプライチェーン攻撃 (Mini-Shai-Hulud)と推定

  • 公式の調査進捗や詳細は StepSecurity のブログ(www.stepsecurity.io/blog/mini-shai-hulud-is-back-a-self-spreading-supply-chain-attack-hits-the-npm-ecosystem)で随時共有

  • 通知設定やIssue操作 にはサインインが必要

    • 現在、 リアクション機能 は利用不可
    • 担当者やラベル、マイルストーン の割り当ては未設定
    • プルリクエストやブランチ との関連はなし

開発者・利用者への注意事項

  • npmパッケージの 最新リリース利用時 は十分な注意が必要
  • 疑わしいバージョンのインストール回避 を推奨
  • 公式からの 調査結果や推奨対応 を常に確認
  • サプライチェーン攻撃 への警戒と早期対応の重要性
  • npmエコシステム 全体でのセキュリティ意識向上の必要性

Hackerたちの意見

ミニシャイ・フルードのワームが、CI/CDパイプラインをハイジャックして開発者の秘密を盗むことで、正当なnpmパッケージを攻撃しているよ。StepSecurityのOSSパッケージセキュリティフィードが最初に公式の@tanstackパッケージでこの攻撃を検出して、エコシステム全体での広がりをリアルタイムで追跡しているんだ。

どうやってそれを検出したの?内部で使ってるの?それとも人気のパッケージを監視してるの?

せめて1〜2時間だけだったし、react-queryには影響しなかったけど、結構有名なパッケージがやられちゃったね。これ、持続可能じゃない気がする。依存関係が更新されるたびに運試ししてるみたい。

npm環境をしっかり守ることを忘れないでね。https://gajus.com/blog/3-pnpm-settings-to-protect-yourself-f... ちょっとした設定で大きなトラブルを避けられるから。

この記事、npmの最小リリース年齢について間違ってない?1. 設定はmin-release-age。2. なぜか日数にしてるみたいだけど、分かる?: https://docs.npmjs.com/cli/v11/using-npm/config#min-release-... 依存関係管理のスペースが無理に分断されてると思う。

そして、すべての依存関係を絶対に固定してね。もしパッケージのバージョン依存がこんな感じだったら: ^1.0.0 あるいはこれ: "*", もう読むのをやめて、すぐに安全なバージョンに固定して!

最低年齢を7日に設定するっていうのは、俺が「絶対に」サプライチェーンのnpm脆弱性を受けないっていう荒唐無稽な主張だな。

残念だけど、これは証拠だと思う(私の意見だけど)、Trusted PublishingはCIから安全に公開するにはまだ不十分だよ。攻撃者がCIパイプラインの中にいるか、盗まれたリポジトリの管理者権限を持っていれば、簡単に公開できちゃうから。これは新しい情報じゃないけど、TPはこれに対する保証をするためのものじゃないんだ。でも、TPに移行することでローカル公開から2FAを外すと、この種の攻撃がCIの妥協から生まれることになる。 (編集: 「まだ安全でない」を「まだ不十分だ」に変更したのは、私が言いたいポイントだから)Trusted Publishingやパイプライン公開に移行すると、ローカルで作業する際にnpm公開を制限するための第二の要素がなくなっちゃう。ここでの話は、攻撃者がCI/CDパイプラインを妥協した結果、npm公開に第二の要素がないからOIDCトークンを盗んで公開を完了できたってこと。面白いけど、関係ないかもしれないのは、公開ジョブが失敗したこと。だから、悪意のあるコミットにあったペイロードは、ワークフローからOIDCトークンを使って自分自身を公開できるスクリプトを持ってたはず。私が望むのは、CI公開がGithubの外で第二の要素を持ちながら、トークンなしの長期的なTrusted Publisherモデルに依存すること。つまり、私が望むのは段階的な公開で、誰かが2FAを使ってnpm側でアーティファクトを公開する必要があること。そうでないと、公開がGithubの信頼モデル内でしか行えないなら、リポジトリ管理者のトークンを持っているか、悪意のあるコードがパイプラインに入ってしまったら、簡単に公開を完了できちゃう。Githubの文脈の外に真の第二の要素があれば、リポジトリに大きなダメージを与えたり悪意のあるコードを植え付けたりすることはできるけど、少なくともレジストリのための第二の要素を手に入れない限り、公開はできないはず。

アストラルブログが最近、信頼できる公開でもリリースゲート(リリースワークフローの手動承認)をどうやってやってるか指摘してたね。残念ながら、信頼できる公開のためのドキュメント(NPM/PyPi/Rubygems)には、この可能性すら言及されてないし、デフォルトでもないんだよね。

なんでみんなが信頼できる公開がこういうサプライチェーン攻撃に違いをもたらすって言ってるのか、ずっと疑問だった。

YubiKeyとかでタッチしてサインできるようにしたいな。クラウドに認証情報を管理させるって考え自体が間違ってる気がする。

攻撃者がCIをどうやって侵害したのか、分析が楽しみだな。ワークフローを見てたんだけど、すぐに目に入ったのがキャッシュポイズニング攻撃だね。https://github.com/TanStack/config/pull/381を考えると、あり得る話だと思う。

ポストインストールスクリプトは危険すぎる。みんなpnpmを使うべきだよ。フォークにプッシュされた「孤児」コミットが、npmクライアントでこれを引き起こすなんてクレイジーだ。個人的には、ここでの責任の大部分はGitHubにあると思う。悪意のあるフォークのコミットが、正当なリポジトリと区別がつかないURIでGitHubの共有オブジェクトストレージにアクセスできるのは、ほんとにおかしい。

アップデートした依存関係でアプリを実行すると、そのコードは結局実行されるからね。ルートか非ルートかは関係ないし、重要な情報はアプリを実行しているユーザーからアクセスできるから。

トークンを取り消すときは気をつけてね。ペイロードが~/.local/bin/gh-token-monitor.shにデッドマンのスイッチをインストールするみたいで、systemdユーザーサービス(Linux)やLaunchAgent com.user.gh-token-monitor(macOS)として動くんだ。盗まれたトークンでapi.github.com/userを60秒ごとにポーリングして、トークンが取り消されると(HTTP 40x)、rm -rf ~/.を実行するみたい。https://github.com/TanStack/router/issues/7383#issuecomment-...

バックアップを設定しておくべきだったけど、これがきっかけでバックアップを設定する人が増えるなら、それはそれでいいことだね。

そうだとしたら、これはソフトウェア界の本当のテロだね!!

なぜこのコメントが問題ページで投票されているのか理解できない。

TanStack?Jia Tan?これに引っかかる人って誰なんだ???

Reactのウェブ開発界隈ではカルトみたいなもんだよ。「タンスタック」じゃなきゃダメだって言い張る開発者に出会わなくてよかったと思って。

関連:CVE-2024-YIKES https://news.ycombinator.com/item?id=48086082

生活はアートを模倣するね。 https://news.ycombinator.com/item?id=48086082#48087028 https://news.ycombinator.com/item?id=48101453

そろそろみんな各プロジェクトをそれぞれのVMで動かすべきだと思う。最近のLPE脆弱性を考えると、Dockerじゃ全然足りないよ。コンテナは元々セキュリティの境界として使うためのものじゃなかったしね。

幸運なことに、CやC++みたいなより安全な言語エコシステムを使っているプロジェクトは、こういう問題から免れてるね :-)

コンテナにこだわるなら、コンテナごとにVMを立てるのもアリだね。最近は、ランダムなKubernetesサービスじゃなくて、全部VMで動かしてるから、ちょっと楽な週が続いてるよ。

クールダウンを適用するのが、このパッケージを拾わない一番簡単な方法だと思う。安全第一でね。