TanStackのリリースワークフローを経たnpmパッケージの侵害

カテゴリ
マルウェア
目次
  1. 経緯
    1. マルウェアの動作
  2. 時系列
  3. 影響範囲
    1. 作戦全体の規模
    2. OpenAIの社内リポジトリと証明書
    3. 下流の組織の公表
  4. 対応と現状
  5. 未公表の事項
  6. 注
  7. 出典
  8. 更新記録
  9. 関連記事

TanStackの2026年5月11日の事後報告によると、Router/Startのリポジトリのリリースワークフローを経て、npmの@tanstack/*パッケージに悪意ある版が公開された⁠[1]。対象は42パッケージ〔注1〕の計84版だった⁠[1]。TanStackは5月15日の改訂で、3日間の全面的なセキュリティの点検と強化を経て、リポジトリとパッケージの安全について公式に「all-clear」を出した⁠[1]。

経緯

TanStackは事後報告で、攻撃は3つの脆弱性の連鎖によるもので、どれも攻撃に必要で、単独では足りないと説明した⁠[1]。1つ目は、bundle-size.ymlがフォークからのPRに対してpull_request_targetで動き、その文脈でフォークのPRのマージ参照をチェックアウトしてビルドしていたことだった⁠[1]。

2つ目はGitHub Actionsのキャッシュの汚染で、actions/cacheのジョブ後の保存はpermissionsの設定で制限されない⁠[1]。キャッシュのスコープはリポジトリ単位で、pull_request_targetの実行とmainへのpushで共有されていた⁠[1]。3つ目は、release.ymlがnpmのOIDCのtrusted publishingのためにid-tokenのwrite権限を宣言していたことだった⁠[1]。汚染されたキャッシュの中のバイナリは、Runner.WorkerのプロセスのメモリからOIDCトークンを抜き出した⁠[1]。

TanStackの事後報告によると、キャッシュの汚染は2024年に研究者が記した攻撃の類型で、TanStack固有の不具合ではなくGitHub Actionsの既知の設計上の問題である⁠[1]。メモリから抜き出す手法は2025年3月のtj-actions/changed-filesの侵害で使われたものと同じで、Pythonのスクリプトも出典の注記付きでそのまま使われていた⁠[1]。TanStackは、攻撃者は新しい手法を作らず、公開された研究を組み合わせたと記した⁠[1]。

TanStackは、不正な版の公開はOIDCのtrusted publisherの結び付けで認証されていたが、ワークフローのPublish Packagesの手順から出たものではなかったと説明した⁠[1]。テストが失敗してその手順は飛ばされており、テストの間に動いたマルウェアがOIDCトークンを発行させ、registry.npmjs.orgに直接公開を送った⁠[1]。ペイロードがテストを壊したことで攻撃が目立ち、早く検知されたと振り返り、テストを壊さない攻撃者なら何時間も長く気付かれずに公開できたとも記した⁠[1]。

TanStackの5月12日の対策の記事では、メンテナーはフィッシングに遭っておらず、パスワードの漏れやアカウントからのトークンの窃取も無かった⁠[2]。事後報告では、npmのトークンは盗まれておらず、npmの公開ワークフロー自体も侵害されていないと説明した⁠[1]。対策の記事でTanStackは、pull_request_targetはGitHubのセキュリティチームが3年以上前から危険なパターンとして記していたが、自分たちのワークフローに残っており、それが根本原因だったと認めた⁠[2]。

TanStack/routerのフォーク〔注2〕に入れた悪意あるコミットは、「claude <claude@users.noreply.github.com>」の身元で作られていた⁠[1]。TanStackは、この身元は本物のAnthropicのClaudeではなく、作られたGitHubのno-replyのアドレスだと注記した⁠[1]。

マルウェアの動作

TanStackの事後報告では、影響する版をnpm・pnpm・yarnで導入すると、悪意あるoptionalDependenciesの項目が解決され、フォークのネットワークにある孤立したコミットからペイロードが取得される⁠[1]。そのprepareのライフサイクルスクリプトが動き、tarballに紛れ込ませた約2.3 MBの難読化されたrouter_init.jsが実行される⁠[1]。スクリプトはAWSのIMDSとSecrets Manager、GCPのメタデータ、Kubernetesのサービスアカウントのトークン、Vaultのトークン、~/.npmrc、GitHubのトークン、SSHの秘密鍵から認証情報を集める⁠[1]。

送出にはSession/Oxenのメッセンジャーのファイルアップロード網が使われ、攻撃者の管理するC2が無いため、ネットワーク上の対策はIP・ドメインでの遮断だけになる⁠[1]。被害者が保守する他のパッケージをnpmのレジストリで列挙し、同じ注入をして再公開する⁠[1]。

StepSecurityの報告によると、ペイロードは100を超えるファイルパスから認証情報を集め、Claude Code・VS Code・OSのサービスに再起動後も残る仕掛けを置く⁠[7]。盗んだデータは暗号化して、Session ProtocolのCDNとGitHubのGraphQL APIを経て送り出す⁠[7]。ペイロードは「IfYouRevokeThisTokenItWillWipeTheComputerOfTheOwner」という説明のnpmトークンを作り、これを失効させると破壊の処理が動く⁠[7]。StepSecurityは、侵害されたパッケージが有効なSLSA Build Level 3の来歴の証明を持っており、有効な証明の付いた悪意あるパッケージを作る初のnpmワームだとした⁠[7]。

GMO Flatt Securityは、感染した端末では永続化サービスgh-token-monitorがGitHubトークンの有効性を監視し、失効時にホームディレクトリを削除する処理を実行するとした⁠[17]。認証情報の入れ替えより先に、永続化の仕組みを無効にする必要があるとも説明した⁠[17]。

SecurityWeekは、セキュリティ企業Wizの説明として、マルウェアはロシアの利用者への感染を避けるためにシステムの言語を確かめると報じた⁠[10]。イスラエルかイランのロケールのシステムでは、MP3を最大音量で流し、システムのファイルの削除を試みる⁠[10]。

目次へ

時系列

時系列
日付主体内容資料
2026年5月10日17時16分(UTC)攻撃者TanStack/routerのフォークを作り、フォークの一覧の検索を逃れるために改名した⁠[1]
2026年5月10日23時29分(UTC)-偽の身元で、約3万行のJSのペイロードを加えるコミットがフォークに作られた⁠[1]
2026年5月11日10時49分ごろ(UTC)-アカウントzblggがmainに対するPR #7378を開き、pull_request_targetのbundle-size.ymlとlabeler.ymlが自動で動いた⁠[1]
2026年5月11日11時11分〜11時31分(UTC)-PRの先頭に載った悪意あるコミットをbundle-size.ymlのジョブが実行し、1.1 GBのキャッシュ項目がmainのスコープで保存された後、PRは閉じられた⁠[1]
2026年5月11日19時15分〜19時16分(UTC)-Releaseのワークフローの2つの実行で、汚染されたキャッシュが復元された⁠[1]
2026年5月11日19時20分〜19時26分(UTC)-不正な版の公開が2回に分かれてnpmのレジストリに届いた⁠[1]
2026年5月11日19時46分〜19時50分ごろ(UTC)StepSecurity外部の研究者がissue #7383で悪意あるoptionalDependenciesの特徴とパッケージの一覧を示し、npmのセキュリティ担当に通知した⁠[1]
2026年5月11日20時ごろ〜21時3分(UTC)TanStack対応を始め、ほかのチームのGitHubのpush権限を外し、影響した版を3段階で非推奨にした⁠[1]
2026年5月11日21時ごろ〜21時30分(UTC)TanStack全295パッケージの走査で範囲を確定してX・LinkedIn・Blueskyで公表し、全リポジトリのGitHub Actionsのキャッシュを消去した⁠[1]
2026年5月11日22時13分〜23時55分(UTC)npmStepSecurityの通知を受けて、レジストリ側でtarballを削除した⁠[1]
2026年5月12日0時12分(UTC)CVE ProgramCVE-2026-45321を公開した⁠[6]
2026年5月12日5時2分(UTC)TanStacknpmとGitHubのセキュリティ担当にIOCの一覧を送り、tarballの削除を正式に求めた⁠[1]
2026年5月18日12時30分〜13時9分(UTC)攻撃者Nx Consoleの不正な版v18.95.0をVisual Studio MarketplaceとOpen VSXに公開した⁠[3]
2026年5月27日CISACVE-2026-45321を既知の悪用された脆弱性のカタログ(KEV)に加えた⁠[6]

目次へ

影響範囲

TanStackによると、影響したのはRouter/Startのリポジトリのモノレポのパッケージだけで、パッケージごとに約6分の間隔で2版が公開された⁠[1]。Query、DB、Store、AI、Table、Formなど、ほかのリポジトリとパッケージは影響を受けていない⁠[1]。汚染が無いと確かめた系列には、@tanstack/startのメタパッケージも含まれる⁠[1]。Snykは、@tanstack/react-routerだけで週1270万回を超えるダウンロードがあるとした⁠[8]。

作戦全体の規模

StepSecurityは5月11日の報告で、TeamPCPのMini Shai-Huludが新たな波で正規のnpmパッケージを侵害しており、週に数百万回ダウンロードされる@tanstackのパッケージも含まれるとした⁠[7]。ワームはTanStackの外のUiPathやDraftLabなどのパッケージにも広がった⁠[7]。Snykは、TeamPCPが攻撃の実行を公に名乗ったとした⁠[8]。

表1:観測主体と報道が示した作戦全体の規模
項目値示した組織資料
4月29日の波(SAP・Intercom)に続く5月11日の波169パッケージ・373の悪意ある版Snyk⁠[8]
悪意あるパッケージの版169のnpmパッケージ名にわたる373版(うち@tanstackは83版)Aikido⁠[18]
第二波の侵害パッケージ数200超(集計中)GMO Flatt Security⁠[17]
侵害されたパッケージ170超(UiPath 65、Mistral AIのPyPIのパッケージ、OpenSearchのJavaScriptクライアントなど)SecurityWeek⁠[10]
影響したパッケージ170以上のnpmパッケージと2つのPyPIパッケージITmedia NEWS⁠[19]

GMO Flatt Securityは、5月12日に記事を公開したときには、一部のパッケージの悪性バージョンが残っているとした⁠[17]。 The Recordは、英国政府の担当者が、悪意あるパッケージは4月29日と5月11日の2段階でアップロードされたと述べたと報じた⁠[9]。

OpenAIの社内リポジトリと証明書

The Recordは5月14日の記事で、OpenAIがブログで、企業環境の社員の端末2台が攻撃の影響を受けたと述べたと報じた⁠[9]。OpenAIは、2人の社員がアクセスできた社内のソースコードリポジトリの一部で、認証情報を狙った不正アクセスと送出の活動を確認した⁠[9]。送出に成功したのは限られた認証情報だけで、ほかの情報やコードに影響は無いと説明した⁠[9]。

The Recordによると、OpenAIはインシデント対応の会社を雇い、影響したシステムを隔離し、利用者のセッションを失効させ、認証情報を入れ替えた⁠[9]。顧客データが盗まれた証拠は見つかっていない⁠[9]。WindowsとiOSの利用者は対応が要らず、macOSの利用者は更新が必要になると報じた⁠[9]。OpenAIは自社のサイトにも、TanStackのnpmサプライチェーン攻撃への対応の記事を掲載した⁠[14]。

SecurityWeekは、影響したリポジトリにはiOS・macOS・Windows・Androidの製品のコード署名の証明書があり〔注3〕、OpenAIは証明書を失効させてすべてのアプリケーションを署名し直すことにしたと報じた⁠[11]。OpenAIはコードのデプロイのワークフローも一時的に制限した⁠[11]。SecurityWeekによると、OpenAIは3月末のAxiosのサプライチェーン攻撃を受けて強化した構成へ段階的に移行していたが、2台の端末はまだ更新されていなかった⁠[11]。新しい構成なら悪意あるパッケージのダウンロードを防げたと、OpenAIは説明した⁠[11]。

The Hacker Newsは、更新を求められたのはmacOSのChatGPT Desktop、Codex App、Codex CLI、Atlasの利用者で、証明書は6月12日に失効する予定だと報じた⁠[12]。

ITmedia NEWSは、OpenAIは証明書が悪意あるソフトウェアの署名に悪用された証拠を確認していないが、予防措置として証明書のローテーションを実施していると報じた⁠[19]。OpenAIによると、今回の情報漏洩はTeamPCP恐喝グループによる「Mini Shai-Hulud」サプライチェーン攻撃に関連しているとも報じた⁠[19]。

下流の組織の公表

Nxの事後報告によると、Nx Consoleの侵害の起点は、貢献者1人の開発端末だった⁠[3]。この端末は、5月11日20時43分(UTC)のpnpm installで悪意ある@tanstack/zod-adapter@1.166.15を解決した⁠[3]。リポジトリの.npmrcにある7日間のminimum-release-ageの設定は、その機能より古いpnpmに固定されていたため無視された⁠[3]。攻撃者は認証情報の窃取から不正な版の公開までの7日間、気付かれずにNxのGitHubのリポジトリで活動していた⁠[3]。

Nxは、盗まれたGitHub CLIのOAuthトークンで不正な版が公開されたと説明した⁠[3]。不正な版はVisual Studio Marketplaceで約11分、Open VSXで約36分公開されていた⁠[3]。導入はMarketplaceで28件、Open VSXのダウンロードは41件だった⁠[3]。

Grafana Labsの5月19日の告知では、5月11日に悪意ある活動を検知し、GitHubのワークフローのトークンを多数入れ替えたが、入れ替え漏れのトークンで攻撃者がGitHubのリポジトリにアクセスした⁠[4]。

Grafana Labsは5月16日に、コードベースの公開を防ぐための身代金の要求を受け、支払わないと決めた⁠[4]。コードベースはダウンロードされたが、改変はされていない⁠[4]。6月1日の追記では、社内調査が完了し、顧客の本番システムとGrafana Cloudへの不正アクセスは無かったと確かめ、Mandiantに追加の監査を依頼したと説明した⁠[4]。続く6月23日の追記で、事後のレビューの記事を案内した⁠[4]。

Mistral AIは5月12日のアドバイザリで、TanStackの侵害に起因するMini Shai-Huludの攻撃を受け、npmとPyPIのSDKの侵害された版が公開されたと説明した⁠[5]。影響したのは開発者の端末で、全体のインフラへの影響は無かった⁠[5]。

アドバイザリによると、npmの版は5月11日22時(UTC)に公開された⁠[5]。削除は5月12日1時だった⁠[5]。PyPIの版は同じ日の0時に公開され、3時に削除された⁠[5]。

The Recordは、Mistral AIの広報担当者が、5月12日に第三者のソフトウェアのサプライチェーン攻撃でコード管理のシステムの1つが「一時的に」侵害されたと述べたと報じた⁠[9]。中核でない一部のコードリポジトリ以外のデータへのアクセスは無かったとも報じた⁠[9]。

目次へ

対応と現状

TanStackは、npmの認証情報が盗まれた証拠は無いが、5月11日に影響する版を導入した者には、導入したホストから届く認証情報の入れ替えを強く勧めた⁠[1]。対象はAWS・GCP・Kubernetes・Vault・GitHub・npm・SSHの認証情報である⁠[1]。ペイロードはnpm installのライフサイクルの中で動くため、そのホストは侵害された可能性があるものとして扱う必要があるとした⁠[1]。5月15日の改訂では、Router・Startを含め、現在公開中のすべてのTanStackのパッケージのすべての版を導入して安全だと説明した⁠[1]。

TanStackの事後報告によると、検知は外部によるもので、社内の警報が無く、第三者から侵害を知った⁠[1]。対策の会議を始めた直後には、Socket.devから電話で確認の連絡があった⁠[1]。依存するパッケージがあるとunpublishできないnpmの方針のため、ほぼすべての影響パッケージでunpublishができず、npmの削除を待つ数時間、悪意あるtarballを導入できる状態が残った⁠[1]。TanStackは、npmのスコープのメンテナーが7人いることは、同じ被害範囲に対して認証情報の窃取の標的が7つあることを意味するとも記した⁠[1]。

TanStackは事後報告で、GitHub Security Advisoryを公開し、CVEを申請したと説明した⁠[1]。アドバイザリはGitHubのTanStack/routerのリポジトリに掲載した⁠[13]。5月12日の対策の記事では、すでに終えた対策を挙げた⁠[2]。

  • リリースのパイプラインでpnpmのキャッシュを無効にした⁠[2]
  • 影響したワークフローでGitHub Actionsのキャッシュをすべて外した⁠[2]
  • 組織内のすべてのactionをコミットのSHAに固定した⁠[2]
  • npmとGitHubでSMS以外の2要素認証を必須にした⁠[2]
  • CIからpull_request_targetの使用をすべて除いた⁠[2]
  • 導入の待機期間の挙動を受け継ぐため、すべてのリポジトリをpnpm 11に上げた⁠[2]

TanStackはこれから取り組む対策に、zizmorを全リポジトリの必須のPRチェックにすること、.githubのフォルダにCODEOWNERSを置くこと、pnpmのキャッシュをactions/cache/restoreに替えることを挙げた⁠[2]。外部の貢献者がPRを開けないようにする案は議論しているが、決めていないとした⁠[2]。独立した研究者がペイロードのdead-man's switchに気付き、トークンの失効の前に対応者に警告したことを、被害が大幅に悪化しなかった唯一の理由に挙げた⁠[2]。

CVE-2026-45321の記録で、CNAのGitHub_Mは脆弱性の種類をCWE-506(埋め込まれた悪意あるコード)とした⁠[6]。CVSS 3.1の基本値は9.6(Critical)である⁠[6]。

CISAはこの記録の項目で、悪用の状況を「active」とした⁠[6]。CISAのカタログには、このCVEの項目が掲載された⁠[15]。NHS England Digitalは、npmとPyPIの多数のパッケージに影響するサプライチェーン攻撃のサイバーアラートを掲載した⁠[16]。

目次へ

未公表の事項

  • 公開時間の間に影響する版をダウンロードした利用者の数(TanStackは事後報告で、npmのサポートから得る未解決の問いに挙げた⁠[1])
  • スコープのメンテナーの端末が別に侵害されたかどうか(TanStackは未解決の問いに挙げた⁠[1])
  • OpenAIの端末に届いた悪意あるパッケージの名前と経路
  • OpenAIのmacOS向けアプリの更新期限の変更の有無
  • TanStackによる攻撃者の帰属

注

  • 〔注1〕TanStackは対策の記事の改訂で、パッケージ数を当初の第三者の報告にあった14から42に改めた⁠[2]。レジストリで公開されていた時間も、約20分から20〜26分に改めた⁠[2]。
  • 〔注2〕StepSecurityは、フォークを作ったアカウントをvoicproducoes(3月19日作成)とした⁠[7]。TanStackはzblggとvoicproducoesを攻撃者のアカウントに挙げた⁠[1]。
  • 〔注3〕The Recordは、影響したリポジトリにある製品をiOS・macOS・Windowsと報じた⁠[9]。

出典

当事者

関係組織

公的機関

調査・観測

報道機関

更新記録

  • 2026年5月15日:公開した。
  • 2026年5月16日:The Hacker Newsの5月16日に更新された記事(出典12)を加え、OpenAIのmacOS向けアプリの更新の対象と証明書の失効の予定を「影響範囲」に加えた。
  • 2026年5月19日:Grafana Labsの告知(出典4)とAikidoの5月19日に更新された報告(出典18)を加え、Grafana Labsの被害を「影響範囲」に、Aikidoが数えた版の数を表1に加えた。
  • 2026年5月21日:Nxの事後報告(出典3)を加え、Nx Consoleの不正な版の公開を「時系列」と「影響範囲」に加えた。
  • 2026年5月27日:CISAの既知の悪用された脆弱性のカタログの項目(出典15)を加え、「対応と現状」を改めた。
  • 2026年6月1日:Grafana Labsの告知の6月1日の追記(出典4)で示された社内調査の完了とMandiantへの依頼を「影響範囲」に加えた。
  • 2026年6月23日:Grafana Labsの告知の6月23日の追記(出典4)で示された事後のレビューの記事の案内を「影響範囲」に加えた。
  • 2026年8月4日:CVE-2026-45321の記録の8月4日の更新版(出典6)で示されたCISAの項目のKEVへの追加と悪用の状況を「時系列」と「対応と現状」に加えた。

目次へ