TanStackや多くのパッケージに影響 - 詳細な解説と分析

MMaximilian Schwarzmüller
Computing/SoftwareBusiness NewsInternet Technology

Transcript

00:00:00現在、非常に大規模なサプライチェーン攻撃が発生しており、
00:00:06現在進行形です。npmからPythonエコシステムにも拡大しているため、
00:00:12今はnpmやPythonのパッケージをインストールしないでください。また、システム全般のセキュリティを確認してください。
00:00:19それについては別の動画があります。リンクを下に貼っておきますし、この動画でも後ほど触れます。
00:00:23まずは、何が影響を受けているのか、そして自分が影響を受けているか確認する方法を詳しく説明します。
00:00:30始まりはTanStackパッケージ(TanStack Query、Router、Startなど)でした。
00:00:36昨日、5月11日のごく短時間に、いくつかの悪意のあるパッケージ、
00:00:43正確にはすべてのTanStackパッケージの悪意のあるバージョンが公開されましたが、20分以内に封じ込められました。
00:00:50最終的には迅速に検知・封じ込めが行われましたが、その短時間の間に
00:00:57これらすべての悪意のあるパッケージが公開されてしまったのです。そして拡散は続き、
00:01:03今も広がっています。ユーザーが4人しかいないMistralパッケージにまで及びましたが、
00:01:09このマルウェアはワームとして動作し、データや認証情報を盗むため、依然として影響があります。
00:01:16影響の確認方法はすぐに説明しますが、攻撃側はさらなる拡散を狙っており、
00:01:20より多くのnpmパッケージへ、さらにはPythonエコシステムへと広がっています。
00:01:26これは今まさに起きていることです。この録画時点からわずか2時間前の出来事です。
00:01:32では、どうすれば影響を受けているか分かるでしょうか?
00:01:39もし昨日の夜(ドイツ時間)、TanStackパッケージをインストールしたなら、
00:01:45影響を受けていると考えるべきです。その時間帯にインストールした場合は、
00:01:54UTC(協定世界時)であることを念頭に、ご自身のタイムゾーンに換算して判断してください。
00:02:00しかし、Mistralや、ここでは挙げきれないほど多くのJavaScriptパッケージに広がっているため、
00:02:06ご自身のマシンが侵害された可能性を考慮する必要があります。
00:02:13詳細や、公開された影響パッケージの全リストを確認できるよう、リンクを下に共有します。
00:02:18ただ、前述の通りまだ進行中ですので、今は何もインストールしない方がいいかもしれません。
00:02:22侵害の指標(IoC)もあります。特定のファイルハッシュ、
00:02:31RouterのJSファイルのSHAハッシュなどを確認してください。この投稿もリンクしておきます。
00:02:38もしマシンのネットワークリクエストを監視する方法があるなら、
00:02:42このURLへの送信トラフィックを探してください。あればデータが流出した明確な証拠となります。
00:02:48「侵害」とは具体的にどういうことでしょうか? このマルウェアは主に2つのことを行います。
00:02:551つ目はデータの収集です。npmトークン、GitHubトークン、
00:03:03AWSの認証情報、その他のシークレットを探します。システムをスキャンして、
00:03:12認証情報が保存されがちな場所を調べ、収集したものを先ほどのURLに送信します。
00:03:18つまりシークレットを盗むのです。しかし、それだけではありません。
00:03:26ワームとして動作するため、盗んだGitHubトークンも悪用します。例えば、
00:03:33それらとnpmトークンを使って、さらに別の侵害パッケージを公開するのです。あなたが開発者で、
00:03:40その時間帯にTanStackパッケージに依存したCI/CDワークフローを実行していた場合、
00:03:46そのワークフロー内に侵害されたTanStackパッケージが取り込まれてしまいます。
00:03:53そこで悪意のあるコードが実行される可能性があります。そして、あなたのマシンではなく
00:04:00そのワークフロー内で、特定の認証情報が盗まれる可能性があります。
00:04:06その結果、ビルドしようとしていたパッケージの侵害バージョンが公開されてしまうのです。
00:04:14これが拡散の仕組みです。ワームのように動作し、
00:04:20盗んだトークンでさらに汚染パッケージを公開します。そうしてMistralや
00:04:26他のJavaScriptパッケージ、さらにはPythonエコシステムへも広がりました。これが現状です。
00:04:32私の知る限り、今もまだ広がっています。では、どうやって防げばいいのでしょうか?
00:04:39別のチャンネル「AkataMind」で動画を作りました。リンクを下に貼っておきます。
00:04:44手短に言うと、可能であればコードの実行や開発を、
00:04:51ホストマシンで直接行わず、仮想マシンや開発コンテナ内で行うようにしてください。
00:04:57生(プレーンテキスト)のシークレットをマシンに保存してはいけません。AWSなら、
00:05:03IAMの認証情報を保存する代わりに、シングルサインオン(SSO)のアプローチを使いましょう。
00:05:10他のサービスでも同様の手法を検討してください。さらに、
00:05:16InfisicalやDopplerのようなサービスを利用して、
00:05:25シークレットをHDDの .env ファイルではなくクラウドに保存するのも一つの手です。
00:05:30こうした内容も動画で話しています。また、パッケージマネージャーや
00:05:38設定において「最低リリース経過時間」を指定できるものを使いましょう。Bunなどで可能です。
00:05:44bunfig.tomlファイルで最低リリース経過時間を設定すれば、`bun install` を実行しても、
00:05:49公開から一定時間(数秒や数日)経過したパッケージのみをインストールするように制限できます。
00:05:56pnpmや最新バージョンのnpmにも同様の機能があります。これも例の動画で解説しました。
00:06:02Bunなどを使ったり、npmを適切に設定したりすれば(Bunはデフォルトでそうですが)、
00:06:09インストールするパッケージの post install スクリプト、つまりライフサイクルスクリプトの
00:06:15実行をブロックできます。この種のマルウェアは通常、
00:06:21システム上でのそうしたスクリプト実行に依存しているため、もう一つの防衛策になります。
00:06:28安全なパッケージマネージャーや設定の使用、仮想マシンや開発コンテナでの実行、
00:06:36そして生のシークレットを保存しないこと。これらは一般的に推奨されることですが、
00:06:41こうした攻撃が深刻化している今、さらに重要になります。
00:06:46今回の攻撃の手口は非常に興味深いので、詳しく見ていきましょう。
00:06:52もちろん、この種の攻撃は増えています。私もほぼ毎月、あるいはそれ以上の頻度で
00:06:58こうした動画を作っています。その理由の一つは、攻撃が容易になったことにあると思います。
00:07:04AIの時代になり、標的とするパッケージや依存関係を分析したり、
00:07:12ソースコードやCI/CD設定から攻撃ベクトルを探し出したりすることが簡単になりました。
00:07:22TanStackの場合も、メンテナのマシンが直接感染したのではなく、
00:07:28CI/CDワークフローが攻撃されたのです。これについては後で詳しく述べます。
00:07:34AIを使えば脆弱性の発見も、悪意のあるコードの作成も容易です。同時に、
00:07:40ソフトウェアの数が爆発的に増えています。かつてないほど多くのコードが書かれており、
00:07:45セキュリティに無頓着な標的も山ほど存在します。それがこうした攻撃を
00:07:51攻撃者にとって魅力的なものにしています。では、どのように始まったのでしょうか?
00:07:57実に興味深いです。全く新しい手法というわけではありませんが、かなり巧妙です。
00:08:03TanStackチームは事後分析(ポストモーテム)記事を公開し、攻撃の全容を解説しています。
00:08:09それも下にリンクしておきます。ここではそのまとめを説明しますが、
00:08:15この攻撃は主に3つのステップで構成されており、詳しく解説します。
00:08:221つ目は「Pull Request Pwn Request」パターン。2つ目は「フォークベースの信頼境界を越えた
00:08:30GitHub Actions キャッシュ汚染」。そして3つ目は「ランタイムメモリからのOIDCトークン抽出」です。
00:08:38これらは一体どういう意味でしょうか? 詳細は記事を読んでいただくとして、概要をお話しします。
00:08:45まずは「Pull Request Pwn Request」パターンから始めましょう。
00:08:50これを理解するには、GitHub ActionsがGitHubのCI/CDソリューションであることを知る必要があります。
00:08:58GitHub Actionsとは、もちろんGitHubが提供するCI/CDソリューション、CI/CD製品のことです。
00:09:05ちなみに、GitHub Actionsの講座も公開しています。Actionsの設定方法を学びたい方はぜひ。
00:09:10CI/CDタスクへの活用法や、パッケージ、ウェブサイトの公開方法などを解説しています。
00:09:16他のCI/CDツールと同様、GitHub Actionsもワークフローを起動する「イベント」に依存します。
00:09:24CI/CDの本質は自動化にあります。例えば、ウェブサイトのリリースや、
00:09:29メインブランチへのプッシュ時に自動でデプロイを行うといったことです。
00:09:34ワークフローをトリガーするイベントは様々ですが、プッシュはその一例です。
00:09:40「メインブランチにプッシュされた場合」といったように、特定のブランチを
00:09:44フィルタリングしてタスクを実行できます。依存関係のインストール、
00:09:49プロジェクトのビルド、サーバーへのアップロードなどが可能です。そして、もう一つのトリガーが
00:09:56「pull_request_target」です。これは、あなたのリポジトリに対して
00:10:05プルリクエストが開かれた時に有効になります。つまり、誰でもリポジトリをフォークして、
00:10:14そこで変更を加えてプッシュし、元のリポジトリへプルリクエストを送れるということです。
00:10:19それがこのワークフローを起動します。危険に聞こえますか? 実はそうで、今回の攻撃の火種となりました。
00:10:25「pull_request」というトリガーも別に存在します。
00:10:31動作は似ていますが、「pull_request」はフォークされたリポジトリのコンテキストで実行されます。
00:10:38そのため、そこで悪意のあることが行われても、ベースリポジトリには影響せず、問題になりません。
00:10:45しかし、「pull_request_target」は「ベースリポジトリ」のコンテキストで実行されます。
00:10:52これは潜在的に非常に危険です。誰でもプルリクエストを送れるからです。
00:10:58今回のTanStackへの攻撃では、攻撃者はフォークしたリポジトリに
00:11:04ワームやマルウェアを含んだ悪意のあるコードを仕込みました。
00:11:10そしてプルリクエストを送ることで、「pull_request_target」を起動させました。
00:11:20これによりGitHub Actionsのランナーが動き出しますが、
00:11:26それは「ベースリポジトリ」の権限で動作してしまいます。これはどういうことか?
00:11:33攻撃者が直接コードを書き換えたりマージしたりできるわけではありませんが、
00:11:40例えば使用されている「キャッシュ」が、ベースリポジトリから実行される
00:11:46後のGitHub Actions(通常のプッシュイベントなど)と共有されてしまうのです。
00:11:53ここで2つ目の「キャッシュ汚染」が起きました。どういう仕組みかと言うと、
00:12:00攻撃者はフォーク側のコードに、あるコマンドを仕込みました。
00:12:05「pull_request_target」が走った際に `hashFiles` コマンドなどを悪用して、
00:12:11GitHub Actionsのキャッシュに細工したデータを保存させたのです。そもそもキャッシュの目的は、
00:12:17ワークフローの高速化です。依存関係のハッシュをとっておけば、
00:12:23変更がない場合に再インストールする手間と時間を省けます。
00:12:28CI/CDの実行時間はコストに直結するため、これは理にかなった仕組みです。
00:12:33例えば 依存関係をハッシュ化することができます。その意図としては
00:12:39問題は、「pull_request_target」による実行と、通常の「push」による実行が、
00:12:46同じコンテキストで同じキャッシュを共有していたことです。
00:12:52攻撃者はTanStackの依存関係の中に悪意のあるコードを混ぜ込み、それをキャッシュさせました。
00:12:56あとは、メンテナが正規のコードをプッシュするのを待つだけです。
00:13:00メンテナがプッシュすると、GitHub Actionsは前回作成された(汚染された)キャッシュを再利用し、
00:13:06悪意のあるコードを正規のワークフロー内に引き込んでしまったのです。
00:13:12こうして悪意のあるコードは、フォークから正規のメンテナによる実行環境へと、
00:13:18キャッシュを「運び屋」として移動しました。そして第3のステップとして、
00:13:24正規のCI/CDワークフロー内に侵入したコードは、npmの短命なトークン(OIDCトークン)を盗み出し、
00:13:31TanStackパッケージの悪意のあるバージョンを公開するために悪用しました。
00:13:39ここで関係するのが、npmの「Trusted Publishing」という機能です。本来は安全性を高めるためのものです。
00:13:46通常、パッケージを公開するにはnpmアカウントでトークンを作成しますが、
00:13:53それが盗まれると誰でも勝手に公開できてしまいます。そこで「Trusted Publishing」では、
00:14:01個人のマシンではなく、GitHub Actionsのような信頼できるプロバイダー経由でのみ公開を許可します。
00:14:08その過程で発行されるトークンは、その時限りの「短命」なものです。
00:14:13しかし、そのトークンを要求する「CI/CDコード自体」が汚染されていれば、
00:14:21悪意のあるコードがその新品のトークンにアクセスできてしまいます。今回起きたのはまさにそれでした。
00:14:28結局のところ、このようにキャッシュが2つの実行環境を繋ぐ輸送手段として悪用されたのです。そして第3のステップとして、
00:14:35そして第3のステップとして、悪意のあるコードがTanStackの通常のCI/CDワークフローに入り込むと、
00:14:44プッシュイベントをきっかけに、有効期限の短いNPMトークン(最終的にはOIDCトークン)を盗み出し、
00:14:54悪意のあるバージョンのTanStackパッケージを公開しました。ここで私が言及しているのは、
00:15:00NPMの「Trusted Publishing」という機能のことです。理論上は、これによって公開がより安全になります。
00:15:04NPMパッケージを公開する方法は、大きく分けて2つあると言えます。
00:15:111つは、NPMアカウントでトークンを作成し、それを使って新しいバージョンを公開する方法です。
00:15:19問題はそのトークンが盗まれた場合、誰でも新しいバージョンを公開できてしまうことです。
00:15:26セキュリティを強化するため、NPMは「自分のマシンからは公開できず、
00:15:33信頼されたプロバイダー経由でなければならない」という信頼済み公開プロセスを導入しました。
00:15:37GitHub Actionsはその1つであり、連携設定を行うことができます。
00:15:44長い説明になりましたが、強調したいのは、システムの安全性を高める努力が必要だということです。
00:15:50この攻撃はすぐに見つかりましたが、それでもまだ収束していません。
00:15:57将来的には、これほど早く発見されない攻撃が出てくる可能性も十分にあります。
00:16:03今回は運が良かっただけで、もっと検知が難しければ被害はさらに拡大していたでしょう。
00:16:08攻撃対象は広がり、AIによって攻撃のハードルも下がっています。
00:16:15不必要なインストールは避け、自身の環境設定を再確認してください。
00:16:21影響を受けたパッケージのリストなど、詳細は下のリンクから確認できます。
00:16:27侵入したコードはそのトークンを悪用し、TanStackパッケージの
00:16:36新しいバージョンを勝手に公開しました。興味深いことに、この攻撃は一部失敗していました。
00:16:44信頼されたトークンを取得し、それを使ってnpm API経由で新バージョンを
00:16:52公開することには成功したのですが、実は最終的に
00:16:58GitHub Actionsのワークフロー自体はエラーで終了していました。CI/CDに送られた
00:17:06コードそのものに不備があったためです。もし攻撃者が、
00:17:12正常なコードがプッシュされるタイミングで攻撃を実行していれば、ワークフローは
00:17:19成功していたはずです。npm APIを直接叩いて手動で公開する必要もなく、
00:17:26今回のようにワークフロー内に悪意のあるコードを注入し、
00:17:32そのままワークフローを完結させてしまえば、侵害されたバージョンのTanStackが
00:17:38公開されます。メンテナによる正規のプッシュに見え、ワークフローも成功しているため、
00:17:45非常に正当な更新に見えたはずです。しかし、ワークフローが失敗したのに
00:17:51新バージョンが公開されているという矛盾を、外部の貢献者が発見したことで、
00:18:00事態が明るみに出ました。GitHub Actionsが失敗しているのに、
00:18:05新しいパッケージが公開されるはずがないからです。この不一致に
00:18:12気づけたおかげで、攻撃を早期に検知できました。この点において、
00:18:19TanStackのメンテナも私たちも運が良かったと言えます。とはいえ、巧妙な攻撃です。
00:18:26誰のマシンも直接侵害せずに行われ、迅速に検知されたとはいえ、
00:18:32依然として拡散が続いているなど、深刻なダメージを与えています。
00:18:41長くなりましたが、システムのセキュリティを強化することの重要性を強調したかったのです。
00:18:49以前お伝えしたように、またこの動画でも触れたように、被害に遭うリスクを
00:18:56最小限に抑える対策が必要です。この攻撃は早期に発見されましたが、まだ収束していません。
00:19:05今後は、これほど早く発見されない攻撃が出てくる可能性も十分にあります。
00:19:11今回は偶然の要素も重なりましたが、もし検知がもっと遅れていれば、
00:19:18被害はさらに甚大なものになっていたでしょう。依然として事態は深刻です。
00:19:24このような攻撃は今後も増えるでしょう。お伝えした通り、攻撃の対象範囲(アタックサーフェス)は
00:19:31拡大しており、かつ魅力的になっています。コードを書く人が増え、
00:19:36セキュリティの知識が乏しい人も多い中、AIが攻撃の実行を助けてしまっています。
00:19:42不必要なインストールは避け、自身の環境を再確認してください。
00:19:48詳細や影響を受けたパッケージの全リストは、下のリンクから確認できます。
00:19:51ぜひチェックしてみてください。

Key Takeaway

GitHub Actionsのキャッシュ共有の仕組みを悪用し、プルリクエストから正規のリリースフローに侵入して認証情報を盗み出すサプライチェーン攻撃が現在進行形で拡大しています。

Highlights

  • 2026年5月11日、TanStack QueryやRouterを含むすべてのTanStackパッケージに悪意のあるバージョンが公開されました。

  • 攻撃者はGitHub Actionsの「pull_request_target」トリガーとキャッシュ汚染を組み合わせ、正規のCI/CDワークフローからOIDCトークンを窃取しました。

  • マルウェアはシステムをスキャンし、npm、GitHub、AWSの認証情報などのシークレットを特定のリモートURLへ送信します。

  • 盗まれたトークンを用いてさらに別の侵害パッケージを公開するワームとして動作し、JavaScriptからPythonエコシステムへも拡散しています。

  • Bunやpnpmの設定でパッケージの最低リリース経過時間を指定することで、公開直後の悪意のあるバージョン更新を回避できます。

Timeline

TanStackから始まった現在進行中のサプライチェーン攻撃

  • npmとPythonのエコシステム全体で大規模なサプライチェーン攻撃が発生しています。
  • TanStack関連の全パッケージが標的となり、悪意のあるバージョンが一時的に公開されました。
  • 攻撃は20分以内に封じ込められましたが、ワーム型の動作により他のパッケージへと拡散が続いています。

2026年5月11日の短時間にTanStackエコシステムで発生した攻撃は、わずか4人のユーザーしかいないMistralパッケージにまで及びました。攻撃者はデータの窃取だけでなく、自己増殖的に被害を広げるワーム機能を実装しています。現在も新しいパッケージへの波及が確認されているため、安易なパッケージのインストールや更新は控えるべき状況です。

侵害の検知方法とシステムへの具体的な影響

  • 特定のSHAハッシュ値やネットワークの送信先URLを確認することで侵害の有無を判断できます。
  • マルウェアはローカルマシンやCI/CD環境からAWSやGitHubの認証情報を収集します。
  • 盗まれたトークンは、攻撃者が管理する正規パッケージの偽バージョンを公開するために即座に悪用されます。

侵害が発生した主な時間帯はUTC基準での5月11日夜間であり、その間にTanStackパッケージをインストールした環境は汚染のリスクがあります。実行されたコードは、.envファイルやシステムディレクトリからシークレットを探し出し、外部サーバーへ転送します。特に開発者のCI/CDワークフロー内で実行された場合、そのプロジェクト自体のリリース権限が奪われる二次被害が発生します。

開発環境を守るための具体的な防御策

  • ホストマシンでの直接開発を避け、仮想マシンや開発コンテナ内でコードを実行します。
  • AWS SSOなどの一時的な認証方式を採用し、生のシークレットをHDDに保存しない運用を徹底します。
  • Bunやpnpmの「最低リリース経過時間」設定を利用し、公開されたばかりのパッケージを遮断します。

シークレット管理にはInfisicalやDopplerのようなクラウドサービスを利用し、ローカルの.envファイルを廃止することが推奨されます。また、多くのマルウェアはインストール後のライフサイクルスクリプト(postinstall)に依存しているため、パッケージマネージャー側でこれらの実行を制限することが有効な防御壁となります。攻撃の容易性がAIによって高まっている現状では、環境設定の再確認が不可欠です。

攻撃の技術的詳細:キャッシュ汚染とOIDCトークンの抽出

  • 「pull_request_target」トリガーにより、フォークされた悪意のあるコードがベースリポジトリの権限で実行されました。
  • 攻撃者は悪意のある依存関係をGitHub Actionsのキャッシュに保存し、正規のプッシュ時にそれを取り込ませました。
  • 正規のワークフロー内に侵入したコードは、npmの「Trusted Publishing」で使用される短命なOIDCトークンを奪取しました。

この攻撃は3つのステップで構成されています。まず外部からのプルリクエストを通じて、ベースリポジトリと共有されているキャッシュ領域を汚染します。次に、正規のメンテナがコードをプッシュした際、ビルドを高速化するためのキャッシュ機能が「運び屋」となり、悪意のあるコードを正規の実行環境へ運び入れます。最終的に、信頼された環境にのみ発行される一時的な公開トークンが、その環境内で動作するマルウェアによって盗み出されました。

早期検知の要因と今後のセキュリティ展望

  • GitHub Actionsのワークフローが失敗したにもかかわらず、npmに新バージョンが公開されている矛盾から発覚しました。
  • 攻撃コードの不備によるエラーが、結果として攻撃の早期発見に繋がりました。
  • AIによる脆弱性分析の効率化により、今後さらに検知が困難な攻撃が増加すると予測されます。

今回の攻撃は外部の貢献者がCI/CDの失敗と公開ステータスの不一致に気づいたことで表面化しました。もし攻撃者がより完璧なコードを使用し、ワークフローを成功させていれば、侵害されたバージョンは正規の更新として見過ごされていた可能性があります。ソフトウェアの爆発的な増加とAIによる攻撃手法の高度化を背景に、開発者はこれまで以上に慎重な依存関係の管理を求められています。

Community Posts

No posts yet. Be the first to write about this video!

Write about this video